【问题标题】:istream::peek curious behavior wrt. EOFistream::peek 好奇的行为 wrt。 EOF
【发布时间】:2012-02-04 12:43:00
【问题描述】:

我刚刚在 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)
}

现在我很好奇为什么 peek 设置 eof 位;我觉得这非常不直观。它应该只是偷看不实际消耗任何东西,也不应该改变流状态。另外,为什么unget 随后不起作用?当good() 为假时,标准是否要求所有操作都是nop?

【问题讨论】:

    标签: c++ stream io eof istream


    【解决方案1】:
    in.get();      // get a char (which turns out to be the last)
                   // curiously ios::eof bit doesn't get set just yet
    

    这不是“好奇”。当读取 由于达到 eof 而失败时,流的 EOF 位被设置;它确实不是的意思是“最后一次阅读把我们带到了eof”。

    c = in.peek(); // attempt to peek, return EOF and now set ios::eof bit
    

    就像现在一样。

    另外,为什么unget 随后不起作用?当good() 为假时,标准是否要求所有操作都是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 位表明流的当前位置是在末尾​​i>。您的代码不会只清除 eof 位。另外,你说ungetpeek返回EOF之后没有意义?
    • @GiovanniFunchal:很抱歉你有这种感觉。如果您的peek 未能从流中产生一个字符(因为没有更多要检索的字符),那么执行unget 有什么意义?没有什么可解开的;您未能从流中产生一个字符。至于你关于流状态清除的评论......我不知道为什么这对你来说是个问题。
    • eof() 标志表明流试图读取最后一个字符。在尝试读取最后一个字符之前,流不知道它是最后一个字符。此标志仅用于检测读取失败的原因:实际上您不想因为消耗了整个文件而报告错误。
    • (哦,我知道您可能正在尝试unget 第三行得到的内容。这是有道理的。不过,您仍然需要先清除流状态。)
    • @AProgrammer:嗯,确实如此! (27.7.2.3/36) 非常好。
    猜你喜欢
    • 2012-12-18
    • 1970-01-01
    • 2020-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-29
    相关资源
    最近更新 更多