【发布时间】:2021-11-19 19:28:27
【问题描述】:
我编写了一个简单的程序来显示前 n 个素数,其中 n 由用户输入。到目前为止,如果用户写入一个整数,它执行得很好。
但是,如果输入不是整数(primes(input) != 1),我希望程序继续要求用户提供有效输入。
我尝试创建一个循环(参见代码)来执行此操作,但程序进入了一个无限循环。
例如,当用户输入一个字母时,程序会无限显示“你想显示多少 n 个第一个素数?”直到我退出。由于某种原因,循环中的 scanf 被忽略了。
各种来源给了我不同的解释,包括缓冲区问题。
发生这种无限循环的确切原因是什么?在输入正确之前,让程序尽可能多地给用户的最佳方法是什么?
代码如下:
#include <stdio.h>
int primes(int input);
int main(void)
{
int input;
printf("How many n first primes do you want to display? ");
scanf("%d", &input);
while(primes(input) != 1)
{
printf("How many n first primes do you want to display? ");
scanf("%d", &input);
}
return 0;
}
int primes(int input)
{
int count1 = 0, count2 = 0, b = 1, n = 2;
if(input>=1)
{
while (count1 < input)
{
b = 1;
count2 = 0;
while (b <= n)
{
if (n%b == 0)
{
count2++;
}
b++;
}
if(count2 == 2)
{
printf("%d\n",n);
count1++;
}
n++;
}
return 1;
}
return 0;
}
【问题讨论】:
-
关键是检查
scanf的return值。 -
当用户输入错误数据时,它会一直保留在标准输入中,直到您使用它。
-
如果你想从用户那里读取一个简单的整数,使用
scanf。但是,如果您想从用户那里读取整数并在用户键入整数以外的内容时执行智能操作,则不要使用scanf。就这么简单。scanf不适合这份工作。你可以花三个小时解决一半的问题,但用户仍然可以输入让你搞砸的病态输入。相反,花一小时学习how to read input using something other thanscanf,你可以做得更好。 -
另见this very similar question。 TL;DR:利用
fgets()和strtol(),当用户输入的长度超过允许的最大行数时,不要忘记丢弃未读字符。
标签: c loops input scanf infinite-loop