给出以下C代码:
int eofCount = 0;
while (true) {
int c = fgetc(stdin);
if (c == EOF) eofCount++;
}
Run Code Online (Sandbox Code Playgroud)
eofCount会不会超过1?
我找不到C文档中的任何内容,描述了在达到EOF之后fgetc会发生什么.我知道我可以自己做这本书,但如果stdlib为我做的那就太好了.
我不是在寻找代码片段,因为我已经用glibc尝试了这个,实际上eofCount在EOF之后增加了.我想stdlib源代码参考或规范,确认这是定义的行为.依赖未定义的行为可能会导致问题.
到达文件结尾后,fgetc 是否在每次调用时都返回 EOF?
它取决于 2 个指标和 I/O 函数调用。
尽管 OP 没有提到,但fgetc(stdin);返回EOF以及它们如何影响后续fgetc()调用的原因不对称有两个原因。此外,使用各种 I/O 函数会影响 2 个指标,进而影响后续fgetc()调用
文件结束。
输入错误。
C 规范在文件结束指示符上是明确的,导致后续的EOF.
如果 stream 指向的输入流的文件结束指示符未设置并且存在下一个字符,则 fgetc 函数获取该字符... C11 §7.21.7.1 2
当文件结束发生或已经发生时,设置一个持久标志:文件结束指示符,因此后续调用fgetc()将返回EOF。
如果设置了流的文件尾指示符,或者如果流位于文件尾,则设置流的文件尾指示符并且
fgetc函数返回EOF... §7.21 .7.1 3
当发生罕见的输入错误时,fgetc()返回EOF,但该事件不会设置文件结束指示符,但会设置错误指示符。EOF即使设置了错误指示符,后续调用也不一定返回。IMO,C 规范在这一点上不够明确。
如果发生读取错误,则设置流的错误指示符,
fgetc函数返回EOF§7.21.7.1 3
对feof()、 和的调用ferror()可用于区分导致 的原因EOF,但也可反映先前的 I/O 活动。因此,好的代码会在EOF返回an 后立即检查这些函数,并在发生后续 I/O 时清除它们。
文件结束指示符和错误指示符可以清除void clearerr(FILE *stream);
该rewind()函数清除 错误指示器。
ungetc()将清除文件结束指示符。
其他 I/O 功能也会影响这些指标。
如果导致第一个的条件被删除并且相应的指示符被清除,则后续调用fgetc()可能不会返回。EOFEOF