#include<stdio.h>
#include<ctype.h>
int main()
{
int number, sum = 0;
// loop body is executed at least once
do
{
printf("Enter a number: ");
scanf("%d", &number);
sum += number;
}
while(number != 0);
printf("Sum = %d",sum);
}
这段代码应该打印用户输入的所有整数的总和。但是,当用户输入一个字母作为输入时,它不会抛出错误,而是进入无限循环,打印“输入数字”语句,但不运行循环中的任何其他语句。
谁能告诉我为什么会发生这种情况?
最佳答案
scanf
很奇怪。它有一个内部缓冲区,并且仅当该缓冲区为空时才会从流中读取。在代码的开头,没有任何内容,因此从标准输入读取一行。然后 scanf
尝试在那里找到一个整数。如果找到整数,它将报告已成功读取一项(通过返回1
)并将读取的值放入提供的指针位置。但是,如果未找到整数,它将返回“0”,表示“成功读取零项”,并且它不会消耗缓冲区中的任何内容。这意味着,下次调用 scanf
时,缓冲区不会为空,因此不会再次提示用户输入新行,并且 scanf
将再次尝试读取与上次尝试完全相同的位置的整数(并且会因完全相同的原因而失败)。因此,无限循环。
为了说明这个“缓冲区”的事情,试试这个:
scanf("%d", &a);
scanf("%d", &b);
printf("a: %d, b: %d\n", a, b);
并在一行中输入 12 53
,作为第一个 scanf
的输入。神奇的是,a
最终为 12
,b
最终为 53
。对这个魔法的解释是 - 第一个 scanf
发现缓冲区为空,从用户那里读取该行,并找到一个整数,正如它被告知的那样;第二个 scanf
发现缓冲区中仍有一些内容,并继续从上次停止的地方读取,而无需要求用户换行。
正如其他人已经评论的那样,通常最好自己读取一行(fgets
)并自己解析它(strtol
),或者如果您绝对需要使用 scanf
,请确保通过检查其返回码来检查 scanf
是否读取了您期望的内容。请参阅here关于如何在 scanf
失败时清除输入缓冲区。
关于c - 输入一个字符作为整型变量的输入,给出无限循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51718925/