stdin 允许读取 EOF 标志集

stdin allows to read with the EOF flag set

在我的平台上,以下代码允许我成功地从 stdin 中读取,即使设置了文件结束标志,该标志在读取后也保持设置状态。要重现该行为,首先键入文件结束快捷方式(Ctrl+D 在 Unix 上,Ctrl+Z on 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):

Returns

If the end-of-file indicator for the stream is set, or if the stream is at end-of-file, the end-of-file indicator for the stream is set and the fgetc function returns EOF

getchar() 等同于 getc(stdin) (7.21.7.6),后者又是 fgetc(stdin) (7.21.7.5) 的宏。所以 getchar() 的行为应该与 fgetc(stdin).

完全一样

在我看来,这不符合标准。我错过了什么吗?


这个问题之前提到了C++(所以在评论里讨论的很长),但是这个问题可以缩小到C标准库,所以我编辑了。以下信息可能仍然相关:

平台之间的行为不一致:

这个问题是 this one 的后续问题,它是关于 cin.clear() 似乎没有取消设置 stdin 的文件结束标志的事实,之后一些有用的评论和聊天讨论。

在 Linux 上,这确实是 st​​dio 实现中的一个已知 glibc 错误:#1190 - from 2005, #19476 - duplicate from 2016 仅在最近的 2.28 版本中得到修复。