scanf无法处理无效输入

时间:2016-11-11 15:23:30

标签: c debugging scanf stdin

在第一个scanf()的字符输入中,第二个不运行。 getchar()无法为Try Again输入工作。它会跳过以获取输入您想再次播放吗? (是/否)?似乎your_choice应该接受角色并在之后检查它,但角色实际上是由ch拍摄的。是什么导致它像这样工作以及如何解决问题。我尝试重新初始化变量但是没有工作。

#include <stdio.h>

void choice(int);

int main() {
    char ch;
    int random, your_choice;

    do {
        srand(time(NULL));
        system("cls");
        printf("** 0 is for Rock **\n");
        printf("** 1 is for Scissors **\n");
        printf("** 2 is for Lizard **\n");
        printf("** 3 is for Paper **\n");
        printf("** 4 is for Spock **\n");

        printf("\nEnter your choice here:");
        scanf("%d", &your_choice);

        random = rand() % 5; //random number between 0 & 4
        if ((your_choice >= 0) && (your_choice <= 4)) {
            //choice printer omitted for this post

            if ((random == ((your_choice + 1) % 5)) || (random == ((your_choice + 2) % 5)))
                printf("\n\n... and you win!!!\n");
            else if ((random == ((your_choice + 3) % 5)) || (random == ((your_choice + 4) % 5)))
                printf("\n\n... and you lose!!!\n");
            else if (random == your_choice)
                printf("\n\nUnfortunately, it's a tie!\n");
        } else
            printf("\nWell, this is wrong! Try again with a number from 0 to 4!!\n");

        printf("\nWould you like to play again? (Y/N)?: ");
        scanf(" %c", &ch);

    } while (ch == 'y' || ch == 'Y');

    return 0;
}

1 个答案:

答案 0 :(得分:4)

如果用户输入无法转换为数字的字符,scanf("%d", &your_choice);将返回0并且your_choice未经修改,因此未初始化。行为未定义。

您应该对此进行测试并以这种方式跳过违规输入:

    if (scanf("%d", &your_choice) != 1) {
        int c;
        /* read and ignore the rest of the line */
        while ((c = getchar()) != EOF && c != '\n')
            continue;
        if (c == EOF) {
            /* premature end of file */
            return 1;
        }
        your_choice = -1;
    }

说明:

  • scanf()返回成功转化的次数。如果用户输入数字,则会将其转换并存储到your_choice,并scanf()返回1,如果用户输入的内容不是数字,例如AA,{{1}将有问题的输入留在标准输入缓冲区中并返回0,最后如果到达文件末尾(用户输入^ Z在windows中输入或^ D在unix中),scanf()返回scanf()

  • 如果输入未转换为数字,我们输入EOF语句的主体:输入一次消耗if一个字节,直到文件末尾或读取换行符。

  • 如果getchar()返回getchar(),我们已经读取了整个输入流,无需提示用户输入更多内容,您可能希望在返回错误代码之前输出错误消息

  • 否则,将EOF设置为your_choice,这是一个无效值,因此读取代码会提示并提示进一步输入。

读取和丢弃有问题的输入是必要的:如果你不这样做,下一个输入语句-1将读取有问题的输入的第一个字符,而不是等待用户输入以响应{{1提示。这是您观察到的行为的解释。