stdin允许使用EOF标志集

时间:2018-04-18 09:33:21

标签: c stdin eof standard-library

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

getchar()相当于getc(stdin)(7.21.7.6),而后者又是fgetc(stdin)(7.21.7.5)的宏。因此getchar()的行为应与fgetc(stdin)完全相同。

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

这个问题以前提到了C ++(因此在评论中进行了长时间的讨论),但问题可以缩小到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()似乎没有取消设置stdin的文件结束标志的事实。评论和聊天讨论。

1 个答案:

答案 0 :(得分:2)

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