C Do while循环不退出,尽管表达式变为false

C Do while循环不退出,尽管表达式变为false,c,switch-statement,break,do-while,C,Switch Statement,Break,Do While,我这里有一个程序,在指定的void方法中包含一个do while循环。我试图退出函数中的循环,这样do while循环就可以按预期的方式工作。除非在我运行该程序并且出现一种情况之后,否则该程序将继续运行,尽管我的while语句声明它只应在while(userInput!=1)下工作。 我不能使用全局变量来解决这个问题,因为我的任务限制了我使用这些技术,因此任何帮助都将不胜感激 以下是我的代码片段: void functionTest() { int gameOver = 0; i

我这里有一个程序,在指定的void方法中包含一个do while循环。我试图退出函数中的循环,这样do while循环就可以按预期的方式工作。除非在我运行该程序并且出现一种情况之后,否则该程序将继续运行,尽管我的while语句声明它只应在while(userInput!=1)下工作。 我不能使用全局变量来解决这个问题,因为我的任务限制了我使用这些技术,因此任何帮助都将不胜感激

以下是我的代码片段:

void functionTest()
{
    int gameOver = 0;
    int userInput;

    do
    {
        printf("please enter a number 1-3");
        scanf("%d",&userInput);

        switch(userInput)
        {
            case 1:
               printf("You entered %d",userInput);
               gameOver = 1;
               break;

            case 2:
               printf("You entered %d",userInput);
               gameOver = 1;
               break;

            case 3:
               printf("You entered %d",userInput);
               gameOver = 1;
               break;
        }
    }
    while(gameOver!= 1);
}
}

问题可能在于使用scanf()时。在按enter键之前输入的内容不是1、2或3。当它要求您输入选项时,您能准确地告诉我们您键入的内容吗

有时,在使用新的scanf()之前,需要刷新标准输出。在扫描线之前尝试fflush(标准输出)。 见和

编辑: 如果我输入除“1”、“2”或“3”之外的任何内容,我可以很容易地重现该问题

我建议您在执行switch语句之前执行以下操作:

  • 在scanf()之前添加fflush(stdout)
  • 将输入接受为字符串(%s),而不是数字。(需要字符[])
  • 修剪尾随空格和前导空格的字符串
  • 使用库函数转换为数字
  • 然后根据这个数字换箱子

  • 问题是,如果在读取整数之前输入流中存在其他字符(不是整数的一部分),则
    scanf()
    将失败,并且永远不会清除不可用的数据。。。这将导致一个无限循环(其中
    scanf()
    多次无法读取与整数相同的字符)

    因此,当
    scanf()
    失败时,或者作为格式的一部分,您需要读取无效字符

    一个简单的解决方案是将您的扫描频率从:

    scanf("%d",&userInput);
    
    致:

    要在读取整数之前读取(并丢弃)输入流中不是数字0-9的任何字符。。。但这仍然不能检查scanf是否因任何其他原因(如关闭的输入流)而失败

    您可以将其替换为以下内容:

    int scanfRes,c;
    do {
        scanfRes = scanf("%d",&userInput); /* try to read userInput */
        /* ..then discard remainder of line */
        do {
            if ((c = fgetc(stdin)) == EOF)
                return; /* ..return on error or EOF */
        } while (c != '\n');
    } while (scanfRes != 1); /* ..retry until userInput is assigned */
    

    …将重试
    scanf()
    ,直到指定字段,每次尝试后丢弃行的剩余部分,如果
    fgetc()
    在执行此操作时遇到错误或EOF,则退出函数。

    为什么用大写字母c写案例?无法复制:发布完整代码,它在程序中的方式,因为它按预期工作。无法重现该问题。放置一个
    printf(“%d\n”,gameOver)在while循环结束时,查看打印的内容。也许这是一个
    scanf
    问题<当输入格式不受尊重时,code>scanf
    会做出奇怪的反应。调试器会说什么?如果看不到完整的代码,很难说,但您可能是正确的。scanf()有时可能是一个无情的野兽:)很容易确定
    scanf
    是否成功读取输入:检查返回值。我同意。在点击开关盒之前,该程序当然需要大量的输入验证/处理,但这需要比OP目前更多的经验。“有时,在使用新的scanf()之前需要刷新标准输出。”我对此表示怀疑。为什么会这样?如果,为什么只是“有时”?Out是Out,in是in,它们是不耦合的。在
    scanf()
    之前不刷新
    stdout
    ,可能会导致显示无序,但不会导致这里的无限循环。
    int scanfRes,c;
    do {
        scanfRes = scanf("%d",&userInput); /* try to read userInput */
        /* ..then discard remainder of line */
        do {
            if ((c = fgetc(stdin)) == EOF)
                return; /* ..return on error or EOF */
        } while (c != '\n');
    } while (scanfRes != 1); /* ..retry until userInput is assigned */