使用字符串流将stderr重定向到stdout

时间:2011-05-24 09:26:02

标签: c++ io stringstream

我有这样的代码

int main()
{
    std::stringstream oss;
    std::cerr.rdbuf( oss.rdbuf() );

    std::cerr << "this goes to cerr";
    std::cout << "[" << oss.str() << "]";
}

但是我得到了程序的输出

[this goes to cerr]Segmentation fault

该程序如何进行分段?

2 个答案:

答案 0 :(得分:12)

这是因为在程序退出之前不会恢复cerr的缓冲区。这样做:

#include <iostream>
#include <sstream>

int main()
{
  std::stringstream oss;
  std::streambuf* old = std::cerr.rdbuf( oss.rdbuf() );

  std::cerr << "this goes to cerr";
  std::cout << "[" << oss.str() << "]";
  std::cerr.rdbuf(old);
}

有关异常安全的解决方案,请参阅this answer of mine

答案 1 :(得分:2)

另一个答案正确地解决了问题的how does this program segfault部分。但是,我认为真正的问题Redirecting stderr to stdout using string stream..应该得到更好的答案:

你可以简化整个shebang,并通过将cerr别名化为cout来使其缩放并更好地执行:

#include <iostream>

int main()
{
    std::cerr.rdbuf(std::cout.rdbuf());
    std::cerr << "this goes to cerr";
}

如果你真的想要明确:

    std::cerr.copyfmt(std::cout);
    std::cerr.clear(std::cout.rdstate());
    std::cerr.rdbuf(std::cout.rdbuf());

您可以验证运行时是否在stdout上实际收到了文本