redirected cout -> std::stringstream, not seeing EOL
-
18-09-2019 - |
Question
I've read a bunch of posts regarding redirecting std::cout to stringstreams, but I'm having problem reading the redirected string.
std::stringstream redirectStream;
std::cout.rdbuf( redirectStream.rdbuf() );
std::cout << "Hello1\n";
std::cout << "Hello2\n";
while(std::getline(redirectStream, str))
{
// This does not work - as the contents of redirectStream
// do not include the '\n' - I only see "Hello1Hello2"
}
I need to pick out the new lines within the initial output - can anyone enlighten me as to how to do that?
Thanks.
Solution
Works fine for me:
Note: the std::getline() reads the line (but not the '\n' character, the line terminator is thrown away after each line is read). But the loop will be entered once for each line.
#include <iostream>
#include <sstream>
int main()
{
std::stringstream redirectStream;
std::streambuf* oldbuf = std::cout.rdbuf( redirectStream.rdbuf() );
std::cout << "Hello1\n";
std::cout << "Hello2\n";
std::string str;
while(std::getline(redirectStream, str))
{
fprintf(stdout,"Line: %s\n",str.c_str());
// loop enter once for each line.
// Note: str does not include the '\n' character.
}
// In real life use RAII to do this. Simplified here for code clarity.
std::cout.rdbuf(oldbuf);
}
Note: you need to put the old stream-buffer back in std::cout. Once the stringstream 'redirectStream' goes out of scope its buffer will be destroyed leaving std::cout pointing at an invalid stream-buffer. Since std::cout lives longer than 'redirectStream' you need to make sure that std::cout does not access an invalid object. Thus the easiest solution is to put back the old buffer.
OTHER TIPS
Thanks for the response. I can kind of see what I've done wrong. Because I stripped out a lot of code to simplify my issue, yes I did actually post a working version! It seems my actual logic was the problem:
// Basically...
std::string str;
std::stringstream redirectstream;
// perform the redirection...
// ...
while (!done)
{
while(std::getline(redirectStream, str))
{
// stuff...
}
std::cout << "Hello1\n";
std::cout << "Hello2\n";
}
It appears that the getline() function no longer appears to be valid in this situation. Can you please explain this?
I realize this is a completely different problem now and I apologize for misleading with a bad initial post.