【问题标题】:Shouldn't istream::peek() always return what you just putback()?istream::peek() 不应该总是返回你刚刚 putback() 的内容吗?
【发布时间】:2013-02-11 19:38:09
【问题描述】:

直观地说,从 C++ 规范来看,在我看来,istream::putback( c ) 似乎应该总是安排输入缓冲区,以便下一次调用 istream::peek() 应该读取字符 c。这不正确吗?我之所以问是因为 Xcode 4.6 附带的最新版本的 libc++ 似乎并未在所有情况下都强制执行此行为——尤其是当最后一个字符位于 EOF 时。如果您使用unget() 而不是putback( c ),情况也是如此。

libc++ 的行为是否正确,或者我对 putback()/unget() 应该如何工作的直觉是否正确?

考虑这个示例代码,它适用于 libstdc++,但不适用于 libc++(断言失败)。

#include <sstream>
#include <cassert>

int main(int argc, const char * argv[])
{
    std::istringstream in( "[Test]" );

    while( in )
    {
        int c = in.get();
        if( c == ']' )
        {
            in.putback( c );
            assert( in.peek() == c );   // Fails with libc++. Succeeds with libstdc++.
            break;
        }
    }

    return 0;
}

【问题讨论】:

  • eofbitfailbitbadbit 是否设置在putback(c) 之后? (供参考:使用 libstdc++ 4.7,这些都没有设置,流是good()。)
  • +1 两个答案。看起来像是在 r162608 中修复的 libc++ 中的错误。

标签: c++ istream libc++


【解决方案1】:

C++11 中的putback 函数实际上已经发生了变化:

§27.7.2.3/34

basic_istream&lt;charT,traits&gt;&amp; putback(char_type c);

效果:表现为未格式化的输入函数(如 27.7.2.3,第 1 段所述),但该函数首先清除 eofbit。 ...

句子的后半部分在 C++03 中不存在。

因此,这可能取决于编译器是否已完全实现此更改,或者您是否使用了所需的选项 (-std=C++11?)。

【讨论】:

    【解决方案2】:

    Bo Persson 关于标准是正确的。您可能使用的是旧版本的 libc++(您的问题出在 LLVM 错误跟踪器中,见下文)。

    在修订版 162108 中引入了更改:

    --- istream     (revision 162607)
    +++ istream     (revision 162608)
    @@ -1263,6 +1263,7 @@
         try
         {
     #endif  // _LIBCPP_NO_EXCEPTIONS
    +        this->clear(this->rdstate() & ~ios_base::eofbit);
             sentry __sen(*this, true);
             if (__sen)
             {
    

    关于变更的日志:

    $ svn log -r 162608

    ----------------------------------- ------------------------- r162608 |希南特 | 2012-08-25 00:03:03 +0200(2012 年 8 月 25 日星期六)| 1 线

    有 basic_istream 的 seekg、putback 和 unget first clear eofbit。修复 http://llvm.org/bugs/show_bug.cgi?id=13089.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-02
      • 1970-01-01
      • 2017-03-10
      • 2012-05-30
      • 2014-12-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多