控制用户在C语言中的输入,当有chars和ints混合的时候

问题描述 投票:0回答:1

所以我想为一个程序做一个简单的菜单,只接受选项1,2和3,我想控制用户输入,以防止错误,比如当用户输入char而不是int时。

现在它控制了一些情况,比如如果选项小于1或大于3,如果选项是char,它也不会影响,但是当用户输入诸如 "02 "或 "2a "时,它会运行选项2,但应该使该选项无效。

另外,如果有更多我遗漏的情况,我想知道它们以及如何克服它们。

#include <stdio.h>
#include <stdlib.h>

void empty_stdin(void);

int main() {
    int option;
    int rtn;

    do {
        printf("\n--\nOptions:\n1.Option 1\n2.Option 2\n3.Option 3\n--\n\nPlease chose option (1/2/3) to continue: ");
        rtn = scanf("%d", &option);

        if (rtn == 0 || option < 1 || option > 3) {
            printf("-Invalid Option-\n");
            empty_stdin();
        } else {

            empty_stdin();

            switch (option) {
                case 1:
                    printf("Option 1");
                    break;

                case 2:
                    printf("Option 2");
                    break;
                case 3:
                    printf("Option 3");
                    exit(0);

                default:
                    printf("\n-Invalid Option-\n");
            }
        }
    } while (option != 3);
    return 0;
}

void empty_stdin(void) {
    int c = getchar();

    while (c != '\n' && c != EOF)
        c = getchar();
}

输入输出示例

--
Options:
1.Option 1
2.Option 2
3.Option 3
--

Please chose option (1/2/3) to continue: 1
Option 1
--
Options:
1.Option 1
2.Option 2
3.Option 3
--

Please chose option (1/2/3) to continue: 12
-Invalid Option-

--
Options:
1.Option 1
2.Option 2
3.Option 3
--

Please chose option (1/2/3) to continue: char
-Invalid Option-

--
Options:
1.Option 1
2.Option 2
3.Option 3
--

Please chose option (1/2/3) to continue: 02
Option 2
--
Options:
1.Option 1
2.Option 2
3.Option 3
--

Please chose option (1/2/3) to continue: 2a
Option 2
--
Options:
1.Option 1
2.Option 2
3.Option 3
--

Please chose option (1/2/3) to continue: 02a
Option 2
--
Options:
1.Option 1
2.Option 2
3.Option 3
-- 

预期的输入输出

--
Options:
1.Option 1
2.Option 2
3.Option 3
--

Please chose option (1/2/3) to continue: 1
Option 1
--
Options:
1.Option 1
2.Option 2
3.Option 3
--

Please chose option (1/2/3) to continue: 12
-Invalid Option-

--
Options:
1.Option 1
2.Option 2
3.Option 3
--

Please chose option (1/2/3) to continue: char
-Invalid Option-

--
Options:
1.Option 1
2.Option 2
3.Option 3
--

Please chose option (1/2/3) to continue: 02
-Invalid Option-
--
Options:
1.Option 1
2.Option 2
3.Option 3
--

Please chose option (1/2/3) to continue: 2a
-Invalid Option-
--
Options:
1.Option 1
2.Option 2
3.Option 3
--

Please chose option (1/2/3) to continue: 02a
-Invalid Option-
--
Options:
1.Option 1
2.Option 2
3.Option 3
--

c input scanf defensive-programming
1个回答
1
投票

考虑使用 fgets 以获取输入和 strtol 来解析一个整数。

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>

int fgetsint ( int *value, int min, int max, FILE *fin) {
    char line[100] = "";
    char extra = '\0';
    char *end = NULL;
    long int number = 0;

    if ( fgets ( line, sizeof line, fin)) {//read a line
        errno = 0;
        number = strtol ( line, &end, 10);
        if ( end == line) {// nothing was parsed. no digits
            printf ( "input [%s] MUST be a number\n", line);
            return 0;// return failure
        }
        if ( ( errno == ERANGE && ( number == LONG_MAX || number == LONG_MIN))
        || ( errno != 0 && number == 0)) {// parsing error from strtol
            perror ( "input error");
            return 0;
        }
        if ( 1 == sscanf ( end, " %c", &extra)) {//parse trailing character
            printf ( "enter one number only. try again\n");
            return 0;
        }
        if ( number > max || number < min) {
            printf ( "Input [%ld] out of range: min: %d max: %d\n", number, min, max);
            return 0;
        }
        if ( 1 != (int)( end - line)) {
            printf ( "input one digit\n");
            return 0;// return failure
        }
        *value = number;//assign number to pointer
    }
    else {
        fprintf ( stderr, "problem fgets\n");
        exit ( EXIT_FAILURE);
    }

    return 1;//success
}

int main ( void) {
    int option = 0;

    do {
        printf("\n--\nOptions:\n1.Option 1\n2.Option 2\n3.Option 3\n--\n\nPlease chose option (1/2/3) to continue: ");

        option = 0;
        fgetsint ( &option, 1, 3, stdin);

        switch (option) {
            case 1:
                printf("Option 1");
                break;

            case 2:
                printf("Option 2");
                break;
            case 3:
                printf("Option 3");
                exit(0);

            default:
                printf("\n-Invalid Option-\n");
        }
    } while ( option != 3);
    return 0;
}

0
投票

下面建议的代码。

  1. 洁净地编译
  2. 执行所需的功能
  3. 处理所有 "哎呀 "的情况
  4. 右边距

现在,拟议的守则。

#include <stdio.h>

void empty_stdin( void );

int main( void ) 
{
    int option = 9;

    do 
    {
        printf("\n--\nOptions:\n"
               "1.Option 1\n"
               "2.Option 2\n"
               "3.Option 3\n"
               "--\n\n"
               "Please chose option (1/2/3) to continue: ");
        option = getchar();

        empty_stdin();

        switch (option) 
        {
            case 1:
                printf( "Option 1\n" );
                break;

            case 2:
                printf( "Option 2\n" );
                break;

            case 3:
                printf( "Option 3, exiting\n" );
                //exit(0);
                break;

            default:
                printf( "\n-option: %d invalid-\n", option );
                break;
        }
    } while ( option != 3 && option != EOF );
    return 0;
}

void empty_stdin( void ) 
{
    //int c = getchar();

    //while (c != '\n' && c != EOF)
        //c = getchar();
    int c;
    while( (c = getchar() ) != EOF && c != '\n' );
}
© www.soinside.com 2019 - 2024. All rights reserved.