如何限制用户输入非数字字符?

时间:2019-05-20 07:49:57

标签: c loops user-input

嗨,请看一下这段代码:

while (cont == 1) {
    ...

    scanf_s("%d", &input);

    if (0 < input <= 5){
        switch (input) {
        case 1:
            printf("1");
            break;
        case 2:
            printf("2");
            break;
        case 3:
            printf("3");
            break;
        case 4:
            printf("4");
            break;
        case 5:
            cont = 0;
            break;

        default:
            printf("Wrong input !");
            break;
        }

    }else{
        printf("Error, Not a number !");
    }
}

如果输入的内容不是数字,则会导致无限循环。如何限制字符输入?

2 个答案:

答案 0 :(得分:0)

您可以使用此:

if(scanf_s("%d", &input) != 1) {
    printf("Wrong input !");
    break;
}

无论如何,您应该始终检查scanf_s的返回值。

答案 1 :(得分:0)

scanf_s()失败后,您需要读取至少一个字符(失败的字符);通常,丢弃用户输入的其余行最有意义:

while (cont == 1) {
    int rc;

    ...

    if ((rc = scanf_s("%d", &input)) < 0)
    {
        printf("EOF detected\n");
        break;
    }
    if (rc == 0)
    {
        int c;
        while ((c = getchar()) != EOF && c != '\n')
            ;
        printf("Error, Not a number!\n");
        continue;     
    }

    if (0 < input <= 5){
        switch (input) {
        case 1:
        case 2:
        case 3:
        case 4:
            printf("%d", input);
            break;
        case 5:
            cont = 0;
            break;
        default:
            printf("Wrong input (1-5 required)!\n");
            break;
        }
    }
}

如果在“ gobble”循环中检测到EOF,则可以在那里检测到EOF,然后重复打印并立即中断循环。 OTOH,下一个scanf_s()也应报告EOF,因此不是100%必要。它在某种程度上取决于提示发生的位置。如果收到EOF,则可能不应该再次提示,因此内部while循环之后的测试应该是:

if (c == EOF)
{
    printf("EOF detected\n");
    break;
}
else
{
    printf("Error, not a number\n");
    continue;
}

您可以使用'gobble'循环的变体来读取换行符或数字,并使用ungetch(c, stdin);将数字返回到输入流,以便下次调用scanf_s()到处理—如果要处理已经输入的数字(可能会造成混淆),您可能不会提示您输入更多信息。

您可以玩其他无尽的游戏。要考虑的一种选择是在放弃之前限制输入失败的次数-如果用户在10次尝试中都没有输入有效的次数,则可能不会。

请注意错误处理如何告诉用户数字的有效范围是什么;可以帮助他们正确处理。还请注意,消息末尾有换行符。这通常是个好主意。在交互式I / O之外的环境中,换行符可以帮助确保输出在打印时显示,而不是在其他任何打印添加换行符或输出缓冲区填满并且毕竟刷新未决数据之后的任意时间。