C语言 如何让用户只输入1-10之间的数字

a64a0gku  于 2022-12-26  发布在  其他
关注(0)|答案(4)|浏览(240)

我正在写一段代码,我想确保用户只输入一个1-10之间的整数,并将该值存储在一个二维数组中。我试图使用指针来完成这项任务。

#include <stdio.h>

int main()
{
    //Declaration of a 2D array
    int movie_Scores [8][5];
    //Declaration of a pointer variable which points to the address of the 1st element
    int *p;
    p=&movie_Scores;
    //Array of pointers to strings and initializtion
    char movie_Names[][100] =      {"1. Movie 1",
                                    "2. Movie 2",
                                    "3. Movie 3",
                                    "4. Movie 4",
                                    "5. Movie 5",
                                    "6. Movie 6",
                                    "7. Movie 7",
                                    "8. Movie 8"
                                   };

    for(int i=0; i<5; i++)
    {
        printf("Judge %d, rate each movie from 1-10:\n\n", i+1);
        for(int j=0;j<8;j++)
        {
            printf("\n%s\t:", movie_Names[j]);
            scanf("%d", (p+i+(j*5)));

            while(*(p+i+(j*5))<1 || *(p+i+(j*5))>10)
            {
                printf("Enter number between 1-10:\n");
                printf("\n%s\t:", movie_Names[j]);
                scanf("%d", (p+i+(j*5)));
            }
        }
    }
}

目前,我的代码接受输入并直接将其存储到数组中,而不检查输入的值是否在1-10之间。

sauutmhj

sauutmhj1#

输入函数不测试有效范围。(事实上,这是scanf的一个已知错误。有关令人眼花缭乱的原因,请参见herehere。)您需要在获得值后测试它。

int value;
if (!scanf( "%d", &value )) fooey();
if ((value < 1) or (value > 10)) fooey();

在C中获取输入实际上是一件相当令人讨厌的事情。你可以自己编写一个帮助函数,把所有杂乱的东西放在一个地方,然后你可以在其他地方使用它。
另外,使用更好的变量名,不要引入不必要的变量。

for(int judge_number=0; judge_number<5; judge_number++)
{
    printf("Judge %d, rate each movie from 1-10:\n", judge_number+1);
    for(int movie_number=0; movie_number<8; movie_number++)
    {
        int rating;
        for (;;)
        {
            printf("%s\t:", movie_Names[movie_number]);
            scanf("%d", &rating);
            if ((rating >= 1) and (rating <= 10)) break;
            printf("Rating must be an integer in 1 to 10.\n");
        }
        movie_Scores[movie_number][judge_number] = rating;
    }
}

编辑:顺便说一句,如果我不提到今天的神奇数字5和8,我将是失职。
你不应该使用幻数,而是在某处提供一个 named 值。

#define NUMBER_OF_MOVIES 8
#define NUMBER_OF_JUDGES 5

然后,您可以在任何需要的地方使用这些标识符:

int movie_Scores [NUMBER_OF_MOVIES][NUMBER_OF_JUDGES];

以及:

for (int judge_number=0;  judge_number<NUMBER_OF_JUDGES;  judge_number++)

等等。

imzjd6km

imzjd6km2#

首先,我将编写一个函数,读取一个int并根据输入检查它,如果读取的是可接受的int,则返回1,如果读取的不是可接受的int,则返回0

int read_int_from_range(int *n, int start, int end) {
    int r = scanf("%d", n);

    return r == 1 && *n >= start && *n <= end;
}

现在,您可以调用它并检查它,然后使用它循环,直到您在另一个函数中获得“有效”的输入(如果需要),或者只是退出并显示错误消息(如果这是所需的行为)。

uz75evzq

uz75evzq3#

如何验证用户实际输入的是整数的问题已经在此问题中得到了回答:
Validate the type of input in a do-while loop C
因此,问题仍然是如何验证用户输入的整数是否也在110的范围内。
为了做到这一点,您只需要一个if语句,但是,如果您希望自动重新提示用户输入,那么您还需要一个循环。
在下面的解决方案中,我使用了上面提到的问题的解决方案中的函数get_int_from_user,并做了一些小的修改,使其接受printf样式的输入,该函数自动验证用户输入的整数是否有效,如果无效,则自动重新提示用户输入。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <limits.h>
#include <errno.h>
#include <stdarg.h>

#define NUM_JUDGES 3
#define NUM_MOVIES 8

int get_int_from_user( const char *prompt, ... );

int main( void )
{
    //Declaration of a 2D array
    int movie_scores[NUM_JUDGES][NUM_MOVIES];

    //Array of pointers to strings and initializtion
    char *movie_names[] = {
        "1. <Movie 1>",
        "2. <Movie 2>",
        "3. <Movie 3>",
        "4. <Movie 4>",
        "5. <Movie 5>",
        "6. <Movie 6>",
        "7. <Movie 7>",
        "8. <Movie 8>"
    };

    for( int i = 0; i < NUM_JUDGES; i++ )
    {
        printf( "Judge %d, rate each movie from 1-10:\n\n", i+1 );

        for( int j = 0; j < NUM_MOVIES; j++ )
        {
            //repeat until the input is in the range 0 to 10
            for (;;)
            {
                int score;

                score = get_int_from_user( "%s: ", movie_names[j] );

                if ( 0 <= score && score <= 10 )
                {
                    //score is good, so write it to the 2D array and
                    //break out of the loop
                    movie_scores[i][j] = score;
                    break;
                }

                printf( "Error: The score must be in the range 0 to 10!\n" );
            }
        }

        printf( "\n" );
    }

    //input is complete, so now it is time to print back the data to the user

    printf( "\nThe following data was entered:\n\n" );

    for ( int i = 0; i < NUM_JUDGES; i++ )
    {
        printf( "Judge %d: ", i+1 );

        for ( int j = 0; j < NUM_MOVIES; j++ )
        {
            printf( "%d ", movie_scores[i][j] );
        }

        printf( "\n" );
    }
}

int get_int_from_user( const char *prompt, ... )
{
    //loop forever until user enters a valid number
    for (;;)
    {
        char buffer[1024], *p;
        long l;
        va_list vl;

        //prompt user for input
        va_start( vl, prompt );
        vprintf( prompt, vl );
        va_end( vl );

        //get one line of input from input stream
        if ( fgets( buffer, sizeof buffer, stdin ) == NULL )
        {
            fprintf( stderr, "Unrecoverable input error!\n" );
            exit( EXIT_FAILURE );
        }

        //make sure that entire line was read in (i.e. that
        //the buffer was not too small)
        if ( strchr( buffer, '\n' ) == NULL && !feof( stdin ) )
        {
            int c;

            printf( "Line input was too long!\n" );

            //discard remainder of line
            do
            {
                c = getchar();

                if ( c == EOF )
                {
                    fprintf( stderr, "Unrecoverable error reading from input!\n" );
                    exit( EXIT_FAILURE );
                }

            } while ( c != '\n' );

            continue;
        }

        //attempt to convert string to number
        errno = 0;
        l = strtol( buffer, &p, 10 );
        if ( p == buffer )
        {
            printf( "Error converting string to number!\n" );
            continue;
        }

        //make sure that number is representable as an "int"
        if ( errno == ERANGE || l < INT_MIN || l > INT_MAX )
        {
            printf( "Number out of range error!\n" );
            continue;
        }

        //make sure that remainder of line contains only whitespace,
        //so that input such as "6sdfj23jlj" gets rejected
        for ( ; *p != '\0'; p++ )
        {
            if ( !isspace( (unsigned char)*p ) )
            {
                printf( "Unexpected input encountered!\n" );

                //cannot use `continue` here, because that would go to
                //the next iteration of the innermost loop, but we
                //want to go to the next iteration of the outer loop
                goto continue_outer_loop;
            }
        }

        return l;

    continue_outer_loop:
        continue;
    }
}

此程序具有以下行为:

Judge 1, rate each movie from 1-10:

1. <Movie 1>: abc
Error converting string to number!
1. <Movie 1>: 4abc
Unexpected input encountered!
1. <Movie 1>: 12
Error: The score must be in the range 0 to 10!
1. <Movie 1>: 1
2. <Movie 2>: 2
3. <Movie 3>: 3
4. <Movie 4>: 4
5. <Movie 5>: 5
6. <Movie 6>: 6
7. <Movie 7>: 7
8. <Movie 8>: 8

Judge 2, rate each movie from 1-10:

1. <Movie 1>: 8
2. <Movie 2>: 7
3. <Movie 3>: 6
4. <Movie 4>: 5
5. <Movie 5>: 4
6. <Movie 6>: 3
7. <Movie 7>: 2
8. <Movie 8>: 1

Judge 3, rate each movie from 1-10:

1. <Movie 1>: 10
2. <Movie 2>: 10
3. <Movie 3>: 10
4. <Movie 4>: 10
5. <Movie 5>: 10
6. <Movie 6>: 10
7. <Movie 7>: 10
8. <Movie 8>: 10

The following data was entered:

Judge 1: 1 2 3 4 5 6 7 8 
Judge 2: 8 7 6 5 4 3 2 1 
Judge 3: 10 10 10 10 10 10 10 10

请注意,出于演示目的,我将NUM_JUDGES5简化为3

jk9hmnmh

jk9hmnmh4#

据我所知,唯一的选择是简单地使用scanf,如果数字小于1或大于10,可以打印类似"Please enter a number from 1 to 10.的内容,然后再次使用scanf,直到得到1到10之间的数字。

相关问题