我碰到这个问题来了,当我要检查什么,我输入号码。 在scanf函数将返回1个,如果我成功地输入数字。 因此,这里是我写的:
int argu;
while(scanf("%d",&argu)!=1){
printf("Please input a number!\n");
}
但是,当像ABCD给它我输入的东西,循环会去永远不会停止的提示。
我在网上看着它,发现它有一些东西做的缓存,我需要把它清理干净,以便scanf函数可以得到新的数据。 所以,我想fflush,但没有奏效。
然后我看到了这一点:
int argu,j;
while(scanf("%d",&argu)!=1){
printf("Please input a number!\n");
while((j=getchar())!='\n' && j != '\n');
}
然后,当像“ABCD”我输入的东西它的工作好,它提示我输入。 但是,当像“12AB”我输入的东西,它不会再工作。
那么,有没有一种方法,我可以检查的scanf(“%d”,&申辩)的输入实际上是一个数字,提示其他输入,如果它不是?
编辑 :
我看到了答案,并通过解决我的问题while(*eptr != '\n')
请注意, fgets
函数实际上读“\ n”的阵列和fget
没有。 所以,要小心。
这是更好地阅读了全系列,使用fgets()
然后检查它,而不是试图解析“对飞”从输入流。
这是容易被忽视的非有效的输入,这种方式。
使用fgets()
然后就strtol()
转换为数字,则可以很容易地看看有没有数后,尾随数据。
例如:
char line[128];
while(fgets(line, sizeof line, stdin) != NULL)
{
char *eptr = NULL;
long v = strtol(line, &eptr, 10);
if(eptr == NULL || !isspace(*eptr))
{
printf("Invalid input: %s", line);
continue;
}
/* Put desired processing code here. */
}
但是,当像ABCD给它我输入的东西,循环会去永远不会停止的提示。
这是因为,如果scanf
遇到不匹配的转换说明一个字符,它留下它的输入流。 基本上,所发生的事情是, scanf
读取字符a
从输入流,则确定这不是用于有效匹配%d
转换说明,然后再将它推回到的输入流。 通过循环下一次它做同样的事情。 然后再次。 然后再次。 然后再次。
fflush
并不是一个很好的解决方案,因为它没有定义为输入流工作。
对于输入"12ab"
, scanf
将读取并转换成"12"
,更让"ab"
输入流。
最好的解决办法是阅读所有的输入文字,然后使用转换为数字类型strtol
(对于整数值)和strtod
(实数值)。 例如:
char input[SIZE]; // assume SIZE is big enough for whatever input we get
int value;
if (fgets(input, sizeof input, stdin) != NULL)
{
char *chk;
int tmp = (int) strtol(input, &chk, 10);
if (isspace(*chk) || *chk == 0)
value = tmp;
else
printf("%s is not a valid integer string\n", input);
}
chk
指向这不是一个十进制数字输入流中的第一个字符。 如果该字符不是空格或0终止子,然后输入字符串不是有效的整数。 这将检测和拒绝输入等"12ab"
以及"abcd"
。
scanf
是一个很好的解决方案,如果你知道你的输入总是会适当地形成乖巧。 如果有一个机会,你输入不乖巧,使用fgets
并根据需要转换。
我会建议得到输入作为一个字符串,并为您在它非数字字符。 如果输入是有效的转换字符串通过为int sscanf(str,"%d",&i);
否则diplay错误。
只需调用scanf函数内环路( “%* [^ \ n] \ n”),它将放弃 “缓存”。
呼叫scanf("%*[^\n]\n")
的环的内侧。 这应该足以放弃与缓存关联东西。