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?
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.
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.
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.
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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With