【问题标题】:stdin allows to read with the EOF flag setstdin 允许读取设置了 EOF 标志
【发布时间】:2018-09-28 11:40:49
【问题描述】:

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


    【解决方案1】:

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

    【讨论】:

      猜你喜欢
      • 2014-06-20
      • 2015-03-25
      • 2018-08-10
      • 2012-12-18
      • 2023-03-14
      • 1970-01-01
      • 1970-01-01
      • 2019-03-24
      • 2021-06-05
      相关资源
      最近更新 更多