Перенаправление stderr на стандартный вывод с использованием потока строк - PullRequest
5 голосов
/ 24 мая 2011

У меня есть такой код

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

Как программа segfault?

Ответы [ 2 ]

12 голосов
/ 24 мая 2011

Это потому, что вы не восстанавливаете буфер 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);
}

См. мой ответ для решения, исключающего исключительную ситуацию.

2 голосов
/ 24 мая 2011

Другой ответ правильно относится к 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());

Вы можете проверить, что текст действительно получен на стандартный вывод при запуске

...