简体   繁体   English

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

[英]Why does inputting an unexpected value type via scanf() cause this program to enter an infinite loop

Consider the following code snippet: 考虑以下代码片段:

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;
    }
}

It works as expected if you enter any integer at the prompt, but If you enter a character, it starts to continually output: 如果在提示符下输入任何整数,它将按预期工作,但是如果输入字符,它将开始连续输出:

How many integers are in your list?

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

...
...
recurse over and over

Obviously it has something to do with the scanf() function, but I would like to know what goes on under the hood that causes this abstraction to leak the way it does. 显然,它与scanf()函数有关,但我想知道导致这种抽象泄漏的方式是如何进行的。

I am used to languages with floaties and life jackets and I am trying to get used to swimming in the deeper end of the swimming pool with C. 我已经习惯了使用漂浮物和救生衣的语言,并且我正试图习惯于使用C在更深的游泳池中游泳。

If you enter a character then scanf() fails and the results are not defined after that and also the input is not consumed and stays in the buffer recursively fetching the same value causing your scanf() to fail repeatedly. 如果输入一个字符,则scanf()失败,并且在此之后未定义结果,并且该输入也未被使用,并且停留在缓冲区中以递归方式获取相同的值,从而导致scanf()反复失败。

So you should do 所以你应该做

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

Because the scanf function will only extract the input if it's correct. 因为scanf函数只会在正确的情况下提取输入。 If the input is not correct, the input will still be in the input buffer when the loop iterates, and the next call to scanf will read the exact same input. 如果输入不正确,则循环迭代时该输入仍将位于输入缓冲区中,并且对scanf的下一次调用将读取完全相同的输入。

You might want to either use the return value of scanf to determine if you should exit the loop, or use eg fgets to read and extract the complete line, and then use eg strtol (or sscanf ) to get the value. 您可能想要使用scanf的返回值来确定是否应该退出循环,或者使用例如fgets读取并提取完整行,然后使用例如strtol (或sscanf )来获取该值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM