警告:fflush(stdin);
可能是未定义的行为。读:Why fflush(stdin)是错的?
int fflush(FILE *ostream);
The ostream
指向输出流或更新流,其中
最近一次操作未输入,则fflush
函数导致任何
该流的未写入数据将被传送到主机环境
写入文件;否则,behavior
is Undefined
.
您可以尝试循环并阅读直到EOF
or \n
given 此常见问题解答条目代替fflush(stdin)
正如我在下面的回答中所建议的。
编辑:感谢@乔纳森·莱夫勒:
有一些平台fflush(stdin)
已完全定义(作为该平台上的非标准扩展)。主要的例子是一个众所周知的系统系列,统称为 Windows。微软的规范int fflush( FILE *stream ); If the stream
开放输入,fflush
清除缓冲区的内容.
我对你的代码还有更多疑问;什么是M
在表达中unsigned int b = pow(2,M-1);
?如果你不定义它应该是一个错误。你发布完整的代码吗?
关于错误检测的逻辑:
如果用户输入无效,则重新读取该值
No, scanf()
不返回错误代码。它返回成功转换的数量。
int scanf ( const char * format, ... );
返回值
成功时,该函数返回成功填充的参数列表的项目数。这个计数可以匹配
预期的项目数量或由于匹配而更少(甚至为零)
失败、读取错误或到达文件结尾。
如果发生读取错误或到达文件末尾
读数,设置正确的指示器(feof
or ferror
)。并且,如果有一个
在成功读取任何数据之前发生,EOF
被返回。
如果解释宽字符时发生编码错误,
功能集errno
to EILSEQ
.
因此,实际上根据遇到的错误,返回值可能为零,即 EOF。你应该使用int ferror ( FILE * stream ); and errno用于错误检测的宏(检查链接中给出的示例)。
可能出现错误的原因是输入无效可:
EILSEQ
:输入字节序列不形成有效字符。
EINVAL
:没有足够的论据;或格式为 NULL。
ERANGE
:整数转换将超出相应整数类型可以存储的大小。
Check 扫描手册以获得完整列表。
无限循环的原因:
系统会跟踪到目前为止已看到的输入。每次致电scanf
从最后一个停止匹配输入的位置开始。这意味着如果之前发生错误scanf
,它无法匹配的输入仍然未读,就好像用户提前输入了一样。如果不小心丢弃错误输入,并且使用循环来读取输入,则您的程序可能会陷入无限循环。
例如在您的代码中:
x = scanf("%u", &a);
// ^
// need a number to be input
但是假设您没有输入数字,但输入了无效字符串,例如"name"
(而不是像你所说的数字)。这将导致scanf()
尝试匹配无符号整数时函数失败("%u"
),以及这个词"name"
未读。所以下一次循环时,scanf()
不等待新的用户输入,它会尝试再次转换“名称”。
类似地,如果输入是29.67
, the "%u
" 将仅匹配前两个字符(29
),留下.67
作为下次调用的未读输入scanf()
.
即使输入正确,如29
,结束输入的换行符仍然未读。通常这不是问题,因为大多数转换会自动跳过前导空白,例如上一行的尾随换行符。然而一些转换("%c"
and "%["
)不要跳过任何前导空格,因此您必须手动执行此操作。
为了避免这种无限循环,一个建议是:
(记住:正如我建议使用ferror()
,错误值更适合检测无效输入。此外,它仅用于学习目的,如果您需要实现一个严肃的应用程序,您应该使用fgets(str)
代替scanf()
接下来是解析str
输入验证输入是否有效)
input:
//fflush(stdout); //use if needed, as \n used in printf no need of fflush-stdout
printf("\nEnter any integer: ");
x = scanf("%u", &a); // always wait for new symbols
printf("%u", a);
if(x == 0){ // x=0, if error occurred
// read all unread chars
while ((ch = getchar()) != '\n' && ch != EOF);
goto input;
}
这只是一个可能适用于您的代码的建议(对我有用,您的代码+ gcc)。但如果您错误地使用此技术,可能会在代码中留下错误:
Read 如何刷新输入缓冲区?
如果您确定输入流中存在不需要的数据,则可以使用
下面的一些代码片段可以删除它们。但是,如果您
当输入流中没有数据时调用这些,程序将
等到出现为止,这会给您带来不良结果。