stdin 允许读取 EOF 标志集
stdin allows to read with the EOF flag set
在我的平台上,以下代码允许我成功地从 stdin
中读取,即使设置了文件结束标志,该标志在读取后也保持设置状态。要重现该行为,首先键入文件结束快捷方式(Ctrl+D 在 Unix 上,Ctrl+Z on 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):
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 returns 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, Built by MSYS2 project) 7.2.0: can read after 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
的文件结束标志的事实,之后一些有用的评论和聊天讨论。
在 Linux 上,这确实是 stdio 实现中的一个已知 glibc
错误:#1190 - from 2005, #19476 - duplicate from 2016 仅在最近的 2.28 版本中得到修复。
在我的平台上,以下代码允许我成功地从 stdin
中读取,即使设置了文件结束标志,该标志在读取后也保持设置状态。要重现该行为,首先键入文件结束快捷方式(Ctrl+D 在 Unix 上,Ctrl+Z on 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):
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()
等同于 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, Built by MSYS2 project) 7.2.0: can read after 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
的文件结束标志的事实,之后一些有用的评论和聊天讨论。
在 Linux 上,这确实是 stdio 实现中的一个已知 glibc
错误:#1190 - from 2005, #19476 - duplicate from 2016 仅在最近的 2.28 版本中得到修复。