为什么fflush(stdin)在while循环中执行两次scanf()输入检查?

时间:2014-05-29 20:05:50

标签: c linux gcc scanf fflush

初学者程序员在这里学习C

我的部分代码要求用户输入数字,并进入while循环以检查输入的值是否为数字,如果不是,则while循环将清除输入(停止无限循环),并询问又一个数字。

问题是,当我清除输入然后在while循环中再次请求scanf()时,它显然会清除它两次,我必须再次输入该数字才能得到我的结果。

以下是相关代码的一部分:

int askNum()
{
    int number;
    int check;

    printf("Enter a number: ");
    check = scanf("%d", &number);

    while(scanf("%d", &number) != 1)
    {
        printf("You've entered an incorrect number.\nEnter a number: ");
        fflush(stdin);
        check = scanf("%d", &number);
    }    
    return number;
}

如果有人可以解释为什么会这样做,请解释或给我一些关于如何继续的提示。

非常感谢你!

2 个答案:

答案 0 :(得分:3)

因为你的while()错了。

此外,fflush()仅为输出流定义。如果你想要可移植的代码,你应该这样做:

void fpurge(FILE *pf)
{
    int c;
    while((c=fgetc(pf)) != '\n' && c != EOF)
    { }
}

它会可靠地读取字符直到行尾。

答案 1 :(得分:3)

fflush(stdin)未由C标准定义。这意味着不同的编译器可能会用它做不同的事情。我完全忽略了它。很难说你的编译器正在做什么,或者为什么可能会发生与之相关的奇怪事情。

要从程序中获得可靠的行为,请坚持使用标准代码。

你的循环结构是正确的,但fflush(stdin)应该被一些代码替换,以读取和丢弃到目前为止输入的所有字符。由于默认情况下stdin是行缓冲的,这意味着您需要继续阅读,直到您按下换行符然后停止;那么事情将为另一个scanf("%d"做好准备。

有多种方法可以实际编码; Medinoc的答案是一个;另一个是[的{​​{1}}说明符。如果发生EOF,您还需要退出循环。 (否则,如果输入流已关闭,则进入无限循环。)