为什么scanf在一次失败后不等待用户输入?
我在下面的代码中遇到了问题。当我输入任何整数时,即为什么scanf在一次失败后不等待用户输入?,c,scanf,C,Scanf,我在下面的代码中遇到了问题。当我输入任何整数时,即(0-9),则它是确定的。但是当我输入一些其他字符时,例如A,B或任何其他字母scanf()都会失败。然后它不等待任何进一步的输入 我已经附加了一个代码片段。我强烈要求仅使用C标准库进行错误处理 #include <stdio.h> int main() { int choice; while(1) { printf("Enter your choice: "); if(0 =
(0-9)
,则它是确定的。但是当我输入一些其他字符时,例如A
,B
或任何其他字母scanf()
都会失败。然后它不等待任何进一步的输入
我已经附加了一个代码片段。我强烈要求仅使用C标准库进行错误处理
#include <stdio.h>
int main()
{
int choice;
while(1)
{
printf("Enter your choice: ");
if(0 == scanf("%d", &choice))
{
printf("Some error occured\n");
//break;/*I did not want to break this loop as I use this to show menu*/
}
switch(choice)
{
case 0:printf("Case 0\n");break;
case 1:printf("Case 1\n");break;
case 2:printf("Case 2\n");break;
case 3:printf("Case 3\n");break;
case 4:printf("Case 4\n");break;
case 5:printf("Case 5\n");break;
case 6:printf("Case 6\n");break;
case 7:printf("Case 7\n");break;
case 8:printf("Case 8\n");break;
case 9:printf("Case 9\n");break;
default:printf("Default case\n");break;
}
}
}
#包括
int main()
{
智力选择;
而(1)
{
printf(“输入您的选择:”);
如果(0==scanf(“%d”,&choice))
{
printf(“发生了一些错误\n”);
//break;/*我不想打断这个循环,因为我用它来显示菜单*/
}
开关(选择)
{
案例0:printf(“案例0\n”);中断;
案例1:printf(“案例1\n”);中断;
案例2:printf(“案例2\n”);中断;
案例3:printf(“案例3\n”);中断;
案例4:printf(“案例4\n”);中断;
案例5:printf(“案例5\n”);中断;
案例6:printf(“案例6\n”);中断;
案例7:printf(“案例7\n”);中断;
案例8:printf(“案例8\n”);中断;
案例9:printf(“案例9\n”);中断;
默认值:printf(“默认情况”);中断;
}
}
}
更清楚的问题是:为什么它不在失败后等待?这是设计的
不要使用break,使用continue和
scanf
,如果给定的输入与格式规范不匹配,则不会使用该输入并保留在输入缓冲区中。换句话说,不匹配的字符永远不会被读取
因此,当您键入字符(例如a字符)时,代码将无限循环,因为scanf
在同一字符上继续失败
当scanf
返回错误时,您需要清除有问题的字符
您不知道将键入多少个字符,但使用任何有问题的字符的一种简单方法是在scanf失败时尝试读取字符串:
char junkChars[256];
printf("Enter your choice: ");
if (scanf("%d", &choice) == 0)
{
printf("Some error occured\n");
scanf("%s", junkChars);
}
这将清除输入缓冲区,但依赖于上限。如果用户键入的字符超过256个,则scanf
将在下一次迭代中继续使用这些字符
显然,这是一个丑陋的解决方案,但是出于这个原因,
scanf
并不是一个很好的输入机制。最好使用fgets
将输入行作为字符串获取,然后自己控制该字符串的解析。我想知道为什么不进一步等待输入,以及如何管理错误以便再次获取输入。为什么要等待?当你点击回车键时,你说的是读字符串。如果出现错误,您需要决定是重试还是中止程序。这可以正常工作,但C库提供了一些清除输入缓冲区的功能。就像它们为输出缓冲区提供了类似于fflush()的功能一样。没有清除输入缓冲区的标准功能(尽管某些实现可能提供)。只需读取输入,例如使用fgets()。这只是像fflush()那样的函数调用;do c=getchar();而(c!=EOF&&c!='\n')是我读取和丢弃输入的首选方式;它的优点是不需要临时缓冲区(只有一个int
),并且可以处理任意长度的垃圾输入。