【发布时间】:2018-09-28 11:40:49
【问题描述】:
在我的平台上,以下代码允许我从stdin 成功读取,即使它的文件结束标志已设置,读取后它也保持设置。要重现该行为,首先键入文件结尾快捷方式(在 Unix 上为 Ctrl+D,Ctrl+Z kbd> 在 Windows 上),然后键入一个普通字符。
#include <stdio.h>
// first type the shortcut for EOF, then a single character
int main(void) {
getchar();
printf("feof(stdin): %s\n", feof(stdin) ? "true" : "false");
int ch = getchar();
if (ch == EOF) return 0;
printf("%c\n", (char) ch);
printf("feof(stdin): %s\n", feof(stdin) ? "true" : "false");
}
我得到的输出(输入字母f后):
feof(stdin): true
f
feof(stdin): true
来自 C11 标准(7.21.7.1,fgetc 函数,3):
退货
如果设置了流的文件结束指示符,或者如果流处于文件结束位置,则设置流的文件结束指示符并且
fgetc函数返回@987654328 @
getchar() 等价于 getc(stdin) (7.21.7.6),后者又是 fgetc(stdin) (7.21.7.5) 的宏。所以getchar() 的行为应该与fgetc(stdin) 完全一样。
在我看来,这不符合标准。我错过了什么吗?
这个问题之前提到了C++(因此在cmets中进行了长时间的讨论),但是问题可以缩小到C标准库,因此我进行了编辑。以下信息可能仍然相关:
平台之间的行为不一致:
- Arch Linux、GCC 7.3.1:可以在 EOF 之后读取;
- Windows 7,GCC(Rev1,由 MSYS2 项目构建)7.2.0:可以在 EOF 之后读取;
- MacOS High Sierra、Apple LLVM 版本 9.0.0 (clang-900.0.39.2):无法在 EOF 之后读取;
- FreeBSD 10.3、clang 3.4.1 和 GCC 5.4.0:无法在 EOF 之后读取。
这个问题是this one 的后续问题,这是关于cin.clear() 在一些有用的cmets 和聊天讨论之后似乎没有取消设置stdin 的文件结束标志的事实。
【问题讨论】:
标签: c stdin eof standard-library