Пренасочване на stderr към stdout с помощта на поток от низове

Имам код като този

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?


person Prasanth Madhavan    schedule 24.05.2011    source източник
comment
Откъде идва [here's some text]?   -  person Oliver Charlesworth    schedule 24.05.2011
comment
@Prasanth: Моля, опитайте да публикувате минимален, компилируем и изпълним пример, който възпроизвежда грешката. Иначе можем само да гадаем.   -  person Björn Pollex    schedule 24.05.2011
comment
съжалявам.. това беше грешен резултат...   -  person Prasanth Madhavan    schedule 24.05.2011
comment
Получавате ли срива с публикувания по-горе код?   -  person Naveen    schedule 24.05.2011
comment
да.. gdb дава това.. (gdb) стартиране [ето малко текст] Програмата получи сигнал EXC_BAD_ACCESS, Не може да получи достъп до паметта. Причина: 13 на адрес: 0x00000000000000000 0x00007fff80e8c5f8 в std::ostream::flush ()   -  person Prasanth Madhavan    schedule 24.05.2011
comment
възможен дубликат на Възможно ли е да се подготви вход от cin?   -  person Nawaz    schedule 24.05.2011
comment
Свързани: еквивалент на freopen() за c++ потоци   -  person finnw    schedule 24.05.2011


Отговори (2)


Това е така, защото не възстановявате буфера на 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);
}

Вижте този мой отговор за решение, което е безопасно по изключение .

person Björn Pollex    schedule 24.05.2011
comment
това работи.. благодаря ви.. въпреки че това е само за пренасочване на cerr към stdout.. не работи за пренасочване на stderr.. защо е така? - person Prasanth Madhavan; 24.05.2011
comment
@Prasanth: Работи за пренасочване на всеки iostream към който и да е друг iostream, но изисква някои незначителни модификации. - person Björn Pollex; 24.05.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());

Можете да проверите дали текстът действително е получен на stdout при изпълнение

person sehe    schedule 24.05.2011