stdin允许读取EOF标志集 [英] stdin allows to read with the EOF flag set
问题描述
在我的平台上,即使设置了文件结束标志,以下代码也允许我成功地从 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屋!