[英]Scanf and loops
这里是一段代码,应该循环遍历,直到用户输入0到15之间的数字
int input;
do
{
printf("Enter a number => ");
scanf("%d",&input);
printf("\n %d \n",input);
}
while (!(input>0 && input <15));
但是,如果用户输入类似“gfggdf”的内容,则会导致循环重复一遍又一遍,并且从不提示用户再次输入...控制台看起来像这样
Enter a number =>
0
Enter a number =>
0
Enter a number =>
0
Enter a number =>
0
Enter a number =>
0
Enter a number =>
0
(looping indefinitely)
看完这本书之后,似乎我需要做这样的事情来防止这种情况发生。
int input, error, status;
char skip_ch;
do
{
error = 0;
printf("Enter a number => ");
status = scanf("%d",&input);
printf("\n %d \n",input);
if(status!=1)
{
error=1;
}
else if(input < 0 || input >15){
error = 1;
}
do
{
scanf("%c",&skip_ch);
}while(skip_ch != '\n');
}
while (error);
我理解需要检查scanf状态以确保它是有效输入,我不理解内部do-while循环。 我觉得这本书从来没有真正向我解释为什么需要多次调用scanf,就像扫描缓冲区填充了一堆垃圾一样,它只是通过循环遍历它一百万次来清理它您。
有人可以向我解释这个黑魔法吗?
这就是为什么有很多类似问题的答案,建议不要使用scanf()
。
此外,您应该检查scanf()
的返回值,因为它会告诉您何时出错 - 并且无法转换任何值。
通常推荐的解决方案是fgets()
读取输入行和sscanf()
的组合,一旦读取就解析行。
示例中的第二个循环用于读取字符,包括换行符,从而重新同步scanf()
并跳过任何虚假数据。 这是一种冗长的做法; 使用getchar()
会更简单:
int c;
while ((c = getchar()) != EOF && c != '\n')
;
注意使用' int c;
' - 类型关键不是' char
'或' unsigned char
',因为它必须存储所有可能的char
值加EOF。
原代码循环下去,因为无效的数据(以下简称“gfggdf”) 不从输入缓冲区中取出时scanf函数无法将其转换为整数-它留在输入缓冲器,因此scanf函数下次调用着眼于同数据,(当然)仍然无法将其转换为整数,因此循环再次执行,结果仍然没有改变。
的:
do {
scanf("%c",&skip_ch);
}while(skip_ch != '\n');
只需一次读取一个字符(并忽略它),直到它到达行尾。 如果你想在没有循环的情况下去除输入缓冲区中的垃圾,你可以使用类似: scanf("%*[^\\n]");
另一种可能(可能更多)被广泛使用的可能性是从读取整行开始,然后尝试转换行中的内容。 无论是否转换,您已经读取了所有数据到行尾,因此无论转换是否有效,下一行读取/转换的下一次尝试都将从下一行开始。 这确实有一个潜在的缺点:如果你有一个很长的输入线,你最终可能会读取并存储大量你没有实际用途的数据。 这很少是一件大事,但你仍应该意识到这一点。
首先,避免使用scanf()
,而是使用fgets()
。
评估您的情况(第一个代码)。 0 > 0
为false
。 0 < 15
是true
。 false && true
是false
。 !false
是true
。 这就是它无限循环的原因。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.