stdin允许读取EOF标志集 [英] stdin allows to read with the EOF flag set

查看:116
本文介绍了stdin允许读取EOF标志集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的平台上,即使设置了文件结束标志,以下代码也允许我成功地从 stdin 读取,读取后该标志也保持设置状态。要重现此行为,请首先键入文件结尾快捷方式(在Unix上为 Ctrl + D ,在 Ctrl + Z

On my platform, the following code allows me to successfully read from stdin even if its end-of-file flag is set, which also remains set after the read. To reproduce the behavior, first type the end-of-file shortcut (Ctrl+D on Unix, Ctrl+Z on Windows) and then type a normal character.

#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后):

The output I get (after typing the letter f):

feof(stdin): true
f
feof(stdin): true

根据C11标准(7.21.7.1, fgetc 函数,3):

From C11 standard (7.21.7.1, The fgetc function, 3):


返回

如果已设置流的文件结束指示符,或者流在文件末尾,则流的文件指示符已设置,并且 fgetc 函数返回 EOF

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)完全一样。

getchar() is equivalent to getc(stdin) (7.21.7.6), which in turn is a macro for fgetc(stdin) (7.21.7.5). So getchar() should behave exactly like fgetc(stdin).

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

It seems to me that this is is not standard compliant. Am I missing something?

这个问题以前是指C ++(因此在注释中进行了长时间的讨论),但是该问题可以限于C标准库,因此我进行了编辑。仍然可能存在以下信息:

This question previously referred to C++ (thus the long discussion in comments), but the problem can be narrowed to the C standard library, thus I edited. Still the following information may be relevant:

平台之间的行为不一致:

The behavior is not consistent among platforms:


  • 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之后都无法读取

  • Arch Linux, GCC 7.3.1: can read after EOF;
  • Windows 7, GCC (Rev1, Built by MSYS2 project) 7.2.0: can read after EOF;
  • MacOS High Sierra, Apple LLVM version 9.0.0 (clang-900.0.39.2): cannot read after EOF;
  • FreeBSD 10.3, both clang 3.4.1 and GCC 5.4.0: cannot read after EOF.

此问题是的后续操作关于 cin.clear()似乎并未取消 stdin 的文件结束标志这一事实,经过一些有用的评论和讨论之后。

This question is a follow-up of this one, which is about the fact the cin.clear() does not seem to unset the end-of-file flag of stdin, after some useful comments and chat discussion.

推荐答案

在Linux上,这确实是一个已知的 glibc stdio实现中的错误:#1190-从2005年起#19476-从2016年起重复仅在最新的2.28版本中得到修复。

On Linux this is indeed a known glibc bug in stdio implementation: #1190 - from 2005, #19476 - duplicate from 2016 which got fixed only in recent 2.28 build.

这篇关于stdin允许读取EOF标志集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆