2012-07-11 38 views
1

我有下面的代码两次结束了,我不明白为什么结果恰好是像下面这样:COUT一个字符串流中损坏COUT(小例子)

#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 

其余的地方??只有当我们取消注释上述行时才输出... 内部会发生什么?有人知道吗? =)会很有趣......

回答

4

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


下面是来自标准(部分27.7.3.6.3),要求该故障位会在这种情况下设置的规则:

basic_ostream<charT,traits>& operator<<(basic_streambuf<charT,traits>* sb);

影响:表现为一个无格式输出功能。在构建哨兵对象之后,如果sb为空,则调用setstate(badbit)(这可能会抛出ios_base::failure)。

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

  • 档案结尾发生在输入序列;
  • 在输出序列中插入失败(在这种情况下,未插入要插入的字符);
  • sb获取字符时发生异常。

如果函数插入任何字符,它调用setstate(failbit)(其可能抛出ios_base::failure)。如果在提取字符抛出了一个异常,该功能处于错误状态设置failbit,如果failbit是在exceptions()捕捉到的异常被重抛出。

返回:*this

+0

这可能是它的的libstdC++文档已经这样说了'__ostream_type& 运营商<<(__ streambuf_type * __sb);' “如果函数没有插入字符,failbit设置。”这看起来似乎是合理的,因为's.rdbuf()'会在第二次尝试打印时结束。 – nos 2012-07-11 21:42:09

+0

哦,谢谢!这就是要点!我们可以在libstdC++ docu中读取哪些内容? – Gabriel 2012-07-11 21:42:47

+1

@ Gabriel:这在标准的第27.7.3.6.3节中有描述。 – 2012-07-11 21:59:01