为什么通过scanf()输入意外的值类型会导致此程序进入无限循环

时间:2015-02-06 14:43:32

标签: c types buffer scanf

请考虑以下代码段:

int n;
int a[100];
int main()
{
    printf("\nThis program will sort a given list of between 1 and 100 integers.\n\n");
    int ready = 0;
    while(!ready)
    {

        printf("How many integers are in your list? ");
        scanf("%d",&n);

        if(n>100)
        {
            printf("\n\nError:\tToo many integers.\n\tThis program can only handle up to 100 integers.\n\n\n"); 
        }
        else if (n<1)
        {
            printf("\n\nError:\tNot enough integers.\n\tThis program requires at least 1 integer to sort.\n\n\n");
        }
        else ready=1;
    }
}

如果在提示符处输入任何整数,它会按预期工作,但如果输入一个字符,它将开始连续输出:

How many integers are in your list?

Error: Too many integers.
       This program can only handle up to 100 integers.

...
...
recurse over and over

显然它与scanf()函数有关,但我想知道引擎盖下导致这种抽象泄漏的方式。

我习惯使用漂浮物和救生衣的语言,我正习惯在C的游泳池深处游泳。

2 个答案:

答案 0 :(得分:3)

如果输入一个字符,那么scanf()会失败并且之后没有定义结果,并且输入也没有被消耗并且以递归方式保留在缓冲区中,获取相同的值会导致scanf()重复失败。 / p>

所以你应该做

if(scanf("%d",&n) == 1)
// Do your stuff

答案 1 :(得分:2)

因为scanf函数只会在输入正确的情况下提取输入。如果输入不正确,则循环迭代时输入仍将在输入缓冲区中,下一次调用scanf将读取完全相同的输入。

您可能希望使用scanf的返回值来确定是否应退出循环,或使用例如fgets阅读并提取整行,然后使用例如strtol(或sscanf)获取价值。