我认为问题在于,如果scanf()
由于 EOF 或输入流中存在非数字字符而失败,那么当您下次调用它时,该问题仍然存在,因此它再次失败,并且这种情况一直持续到程序用完资源或者你的耐心用完了。
至少,您需要区分:
- 好的
- EOF(没有更多可阅读的内容)
- 错误(阅读更多,但下一个字符至少不是数字的一部分)
如果您希望每行有一个数字,那么最好使用fgets()
and sscanf()
。如果您对每行多个数字感到满意,那么您必须更加努力。您可能还应该从函数返回一个值以指示它是否成功。
int input_number(int *number)
{
char line[4096];
while (printf("Number: ") > 0 && fgets(line, sizeof(line), stdin) != 0)
{
if (sscanf(line, "%d", number) == 1)
return 0;
printf("-> Wrong format, try again! <-\n");
}
return EOF;
}
int input_number(int *number)
{
while (printf("Number: ") > 0 && scanf("%d", number) != 1)
{
int c;
if (feof(stdin) || ferror(stdin))
return EOF;
printf("-> Wrong format, try again! <-\n");
while ((c = getchar()) != EOF && c != '\n')
;
if (c == EOF)
return EOF;
}
return 0;
}
注意正确使用feof()
; I/O 操作失败,代码需要区分 EOF 和 I/O 错误以及格式错误。
在第二个函数中,如果printf()
失败,则会错误地告知您读取了一个数字。如果这是一个问题,请添加额外的测试,但该代码已经比使用 的代码更难编写fgets()
,因此在决定使用它时要谨慎。
请注意,原始代码return 0;
中有一个函数返回void
. 该代码应该已被编译器拒绝。