代码之家  ›  专栏  ›  技术社区  ›  Rick Jim DeLaHunt

修改与不修改putback()的区别

c++
  •  4
  • Rick Jim DeLaHunt  · 技术社区  · 7 年前

    问题来自 https://en.cppreference.com/w/cpp/io/basic_istream/putback ,示例代码。

    #include <sstream>
    #include <iostream>
    
    int main()
    {
        std::istringstream s2("Hello, world"); // input-only stream
        s2.get();
        if (s2.putback('Y')) // cannot modify input-only buffer
            std::cout << s2.rdbuf() << '\n';
        else
            std::cout << "putback failed\n";
    
        s2.clear();
        if (s2.putback('H')) // non-modifying putback
            std::cout << s2.rdbuf() << '\n';
        else
            std::cout << "putback failed\n";
    }
    

    s2.putback('Y') 失败但是 s2.putback('H') 成功了吗?后者不也是修改仅输入流缓冲区的操作吗?


    另外,我在做实验的时候发现了一些令人困惑的事情。 与上面的示例相比,我添加了一行代码,第二个结果失败了。。为什么会这样?

    #include <sstream>
    #include <iostream>
    
    int main()
    {
        std::istringstream s2("Hello, world"); // input-only stream
        s2.get();
        if (s2.putback('Y')) // cannot modify input-only buffer
            std::cout << s2.rdbuf() << '\n';
        else
            std::cout << "putback failed\n";
    
        std::cout << s2.rdbuf() << '\n';   //1 line code added
    
        s2.clear();
        if (s2.putback('H')) // non-modifying putback
            std::cout << s2.rdbuf() << '\n';
        else
            std::cout << "putback failed\n";
    
    }
    
    2 回复  |  直到 7 年前
        1
  •  3
  •   xskxzr    7 年前

    你可以进一步了解 sputbackc .

    如果在get区域有一个放回位置( gptr() > eback() gptr() (根据 Traits::eq(c, gptr()[-1]) ,然后简单地递减下一个指针( ).

    所以在这种情况下 s2.putback('H') ,只有下一个指针递减。缓冲区未更改。


    回答您的编辑: basic_ostream& operator<<( std::basic_streambuf<CharT, Traits>* sb); 提取由维护的字符 sb ,所以之后 std::cout << s2.rdbuf() << '\n'; 失败。

        2
  •  4
  •   lubgr    7 年前

    为什么? s2.putback('Y') s2.putback('H') 成功了吗?后者不也是修改仅输入流缓冲区的操作吗?

    s2.回拨('H') 可能 修改缓冲区,但在本例中不会,因为数据已经以 'H' .

    你可以举例说明这样的行为:

    s2.clear();
    
    assert(s2.putback('H')); // Ok, replacing 'H' with 'H' doesn't change anything
    assert(!s2.putback('Z')); // Can't modify.