修改和未修改的putback()之间的区别

时间:2018-09-17 07:02:04

标签: c++

问题来自示例代码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')成功了?后者不是修改输入流缓冲区的操作吗?


此外,在做一些实验时,我感到有些困惑。 与上面的示例相比,我添加了1行代码,第二个结果失败了。为什么?

#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 个答案:

答案 0 :(得分:4)

  

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

调用s2.putback('H') 可能修改缓冲区,但是在这种情况下,不会进行修改,因为数据已经以'H'开头。

您可以举例说明这种行为:

s2.clear();

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

答案 1 :(得分:3)

您可以进一步了解sputbackc的行为。

  

如果在获取区域(gptr() > eback())中有一个回退位置,并且字符c等于gptr()左边的一个字符(由Traits::eq(c, gptr()[-1])确定) ,然后只需递减下一个指针(gptr())。

因此,对于s2.putback('H'),仅下一个指针递减。缓冲区未更改。


回答您的编辑:basic_ostream& operator<<( std::basic_streambuf<CharT, Traits>* sb);提取由sb维护的字符,因此在std::cout << s2.rdbuf() << '\n';之后,下一个指针指向缓冲区的末尾,这导致s2.putback('H')失败。