istream::peek好奇的行为wrt。EOF 我刚刚遇到C++中的一个奇怪的情况。我做了一些类似于: istream in; // ... in.get(); // get a char (which turns out to be the last) // curiously ios::eof bit doesn't get set just yet c = in.peek(); // attempt to peek, return EOF and now set ios::eof bit if(c == EOF) { // realize shouldn't have gotten the last char for some reason in.unget(): // attempt to unget, *fails* (because ios:eof bit was set) }

istream::peek好奇的行为wrt。EOF 我刚刚遇到C++中的一个奇怪的情况。我做了一些类似于: istream in; // ... in.get(); // get a char (which turns out to be the last) // curiously ios::eof bit doesn't get set just yet c = in.peek(); // attempt to peek, return EOF and now set ios::eof bit if(c == EOF) { // realize shouldn't have gotten the last char for some reason in.unget(): // attempt to unget, *fails* (because ios:eof bit was set) },c++,stream,io,eof,istream,C++,Stream,Io,Eof,Istream,现在我很好奇为什么peek会设置eof位;我觉得这很不直观。它应该只是窥视,而不是实际消耗任何东西,并且不应该改变流状态。另外,为什么unget随后不起作用?当good()为false或其他内容时,标准是否要求所有操作都为nop 这并不“奇怪”。当由于达到EOF而导致读取失败时,设置流的EOF位;这并不意味着“最后一次阅读把我们带到了eof” 就像现在一样 另外,为什么unget随后不起作用?当good()为false或其他内容时,标准是否要求所有操作都为nop 。。。这就是正在发生的事情。您未

现在我很好奇为什么peek会设置eof位;我觉得这很不直观。它应该只是窥视,而不是实际消耗任何东西,并且不应该改变流状态。另外,为什么
unget
随后不起作用?当
good()
为false或其他内容时,标准是否要求所有操作都为nop

这并不“奇怪”。当由于达到EOF而导致读取失败时,设置流的EOF位;这并不意味着“最后一次阅读把我们带到了eof”

就像现在一样

另外,为什么
unget
随后不起作用?当
good()
为false或其他内容时,标准是否要求所有操作都为nop

。。。这就是正在发生的事情。您未能以其他方式定义“不起作用”

如果要
unget
第3行检索到的字符,则必须在达到EOF时自己清除流的状态

istream in;
// ...
in.get();      // assume this succeeds (*)

c = in.peek(); // assume this fails and sets EOF bit

if (!in) {
   in.clear(); // clear stream error state for use
   in.unget(); // "put back" that character (*)
}
else {
   // next char from .get() will be equal to `c`
}

我觉得你的答案有点复杂和不清楚。看起来我(错误地)假设eof位表示流的当前位置在末尾。您的代码不会仅清除eof位。还有,在什么基础上,你说
unget
peek
返回
EOF
后毫无意义?@GiovanniFunchal:很抱歉你有这种感觉。如果
peek
未能从流中生成字符(因为没有更多字符可检索),那么执行
unget
有何意义?没有什么可以解开的;您未能从流中生成字符。至于你对流状态清除的评论。。。我不知道为什么这会对您造成问题。eof()标志表示流试图读取的字符超过了最后一个字符。在试图读取最后一个字符之前,流不知道它是最后一个字符。此标志仅适用于检测读取失败的原因:从根本上说,您不想报告由于已使用整个文件而导致的错误。(哦,我看到您可能正试图
unget
第三行上获得的内容。这很有意义。不过,您仍然需要先清除流状态。)@AProgrammer:Hmm,确实如此!(27.7.2.3/36)非常好。
c = in.peek(); // attempt to peek, return EOF and now set ios::eof bit
istream in;
// ...
in.get();      // assume this succeeds (*)

c = in.peek(); // assume this fails and sets EOF bit

if (!in) {
   in.clear(); // clear stream error state for use
   in.unget(); // "put back" that character (*)
}
else {
   // next char from .get() will be equal to `c`
}