问题
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");
}
The output I get (after typing the letter f
):
feof(stdin): true
f
feof(stdin): true
From C11 standard (7.21.7.1, The fgetc
function, 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 returnsEOF
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?
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: 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.
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.
回答1:
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.
来源:https://stackoverflow.com/questions/49896165/stdin-allows-to-read-with-the-eof-flag-set