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

发布于 2024-11-09 00:55:25 字数 324 浏览 0 评论 0原文

我有这样的代码

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

程序段错误如何?

I have a code like this

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

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

But i get the output of the program as

[this goes to cerr]Segmentation fault

How does the program segfault?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

在你怀里撒娇 2024-11-16 00:55:25

这是因为您在程序退出之前没有恢复 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 is because you do not restore the buffer of cerr before your program exits. Do it like this:

#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);
}

See this answer of mine for a solution that is exception safe.

终弃我 2024-11-16 00:55:25

另一个答案正确地解决了您的问题的此程序如何发生段错误部分。然而,我觉得真正的问题 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 上实际接收到文本

The other answer correctly address the how does this program segfault part of your question. However, I feel that the real question Redirecting stderr to stdout using string stream.. deserves a better answer:

You may simplify the whole shebang and make it scale and perform a infitely better better by just aliasing cerr to cout:

#include <iostream>

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

If you really want to be explicit:

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

You can verify that the text is actually received on stdout when run

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文