【问题标题】:cout a stringstream twice ends up in corrupted cout (minimal example)cout a stringstream 两次以损坏的 cout 结束(最小示例)
【发布时间】:2012-07-11 21:20:05
【问题描述】:

我有以下代码,我不太明白为什么结果恰好像下面这样:

#include <iostream>
#include <sstream>

using namespace std;
int main () {

   std::stringstream s;

   std::streambuf *backup;
   backup = cout.rdbuf();


   s << "Oh my god" << endl;


   cout << "Before1" << endl;
       cout << s.rdbuf();
   cout << "After1" << endl;


   cout << "Before2" << endl;
   //s.seekg(0, std::ios_base::beg); // If that is in: After 2 is printed!
   cout << s.rdbuf();
   //cout.rdbuf(backup); // If that is in, also After 2 is printed!
   cout << "After2" << endl;

}

输出:

Before1
Oh my god
After1
Before2

剩下的在哪里??¿ 它只有在我们取消注释上述行时才会被输出...... 内部会发生什么?有人知道吗? =) 会很有趣...

【问题讨论】:

    标签: c++ cout stringstream streambuf


    【解决方案1】:

    检查是否在cout 上设置了失败位。您也可以使用cout.clear() 清除失败位。


    这是标准中的规则(第 27.7.3.6.3 节),要求在这种情况下设置失败位:

    basic_ostream&lt;charT,traits&gt;&amp; operator&lt;&lt;(basic_streambuf&lt;charT,traits&gt;* sb);

    效果:表现为未格式化的输出函数。哨兵对象构造完成后,如果sb为null,则调用setstate(badbit)(可能会抛出ios_base::failure)。

    sb 获取字符并将它们插入*this。从sb 读取字符并插入,直到发生以下任何情况:

    • 文件结束出现在输入序列上;
    • 在输出序列中插入失败(在这种情况下,要插入的字符未被提取);
    • sb 获取字符时发生异常。

    如果函数没有插入字符,它会调用setstate(failbit)(可能会抛出ios_base::failure)。如果在提取字符时引发异常,该函数会将failbit 设置为错误状态,如果failbitexceptions() 中打开,则重新引发捕获的异常。

    返回:*this

    【讨论】:

    • 很可能是这样,libstdc++ 文档对__ostream_type&amp; operator&lt;&lt;(__streambuf_type* __sb);“如果函数不插入字符,则设置了故障位”有这样的说法。这似乎是合理的,因为 s.rdbuf() 将在 2. 尝试打印它时位于其末尾。
    • 哦,谢谢!这就是重点!我们在哪里可以阅读 libstdc++ 文档?
    • @Gabriel:这在标准的第 27.7.3.6.3 节中有描述。
    猜你喜欢
    • 2013-02-25
    • 2023-02-17
    • 2021-11-06
    • 2014-07-20
    • 2012-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多