Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redirecting stderr to stdout using string stream

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?

like image 705
Prasanth Madhavan Avatar asked May 24 '11 09:05

Prasanth Madhavan


People also ask

How would you redirect a command stderr to stdout?

The regular output is sent to Standard Out (STDOUT) and the error messages are sent to Standard Error (STDERR). When you redirect console output using the > symbol, you are only redirecting STDOUT. In order to redirect STDERR, you have to specify 2> for the redirection symbol.

How do I redirect stderr and stdout to a file?

Redirecting stdout and stderr to a file: The I/O streams can be redirected by putting the n> operator in use, where n is the file descriptor number. For redirecting stdout, we use “1>” and for stderr, “2>” is added as an operator.

What is string stream?

The StringStream class in C++ is derived from the iostream class. Similar to other stream-based classes, StringStream in C++ allows performing insertion, extraction, and other operations. It is commonly used in parsing inputs and converting strings to numbers, and vice-versa.

Which is used to redirect both stdout and stderr?

Understanding the concept of redirections and file descriptors is very important when working on the command line. To redirect stderr and stdout , use the 2>&1 or &> constructs.


2 Answers

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.

like image 164
Björn Pollex Avatar answered Oct 24 '22 06:10

Björn Pollex


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

like image 41
sehe Avatar answered Oct 24 '22 08:10

sehe