Redirect both cout and stdout to a string in C++ for Unit Testing
Solution 1
std::stringstream
may be what you're looking for.
UPDATE
Alright, this is a bit of hack, but maybe you could do this to grab the printf output:
char huge_string_buf[MASSIVE_SIZE];
freopen("NUL", "a", stdout);
setbuf(stdout, huge_string_buffer);
Note you should use "/dev/null" for linux instead of "NUL". That will rapidly start to fill up huge_string_buffer. If you want to be able to continue redirecting output after the buffer is full you'll have to call fflush(), otherwise it will throw an error. See std::setbuf
for more info.
Solution 2
You can use freopen(..., stdout)
and then dump the file into memory or a std::string
.
Solution 3
This may be an alternative:
char bigOutBuf[8192];
char savBuf[8192];
fflush(stdout);
setvbuf(stdout,bigOutBuf,IOFBF,8192);//stdout uses your buffer
//after each operation
strncpy(savBuf,bigOutBuf,8192);//won't flush until full or fflush called
//...
//at long last finished
setbuf(stdout,NULL);//reset to unnamed buffer
This just intercepts the buffered output, so still goes to console or wherever.
Hope this helps.
thelsdj
C# business logic programmer by day, electronic music and science fiction fan by night
Updated on June 03, 2022Comments
-
thelsdj about 2 years
I'm working on getting some legacy code under unit tests and sometimes the only way to sense an existing program behavior is from the console output.
I see lots of examples online for how to redirect stdout to another file in C++, but is there a way I can redirect it to an in-memory stream so my tests don't have to rely on the disk?
I'd like to get anything that the legacy code sends to stdout into a std::string so I can easily .find on the output.
Edit
The legacy code is so bad that it users a mixture of
cout << ..
andprintf
. Here is what I have so far:void TestSuite::setUp(void) { oldStdoutBuf = std::cout.rdbuf(); std::cout.rdbuf(consoleOutput.rdbuf()); } void TestSuite::tearDown(void) { std::cout.rdbuf(oldStdoutBuf); }
The problem is that this does not capture output using printf. I would like something that gets both. Any ideas?
-
thelsdj almost 15 yearsI would really like to skip having to use the filesystem. Something that only uses ram would be best.
-
thelsdj almost 15 yearsAccepted your answer as stringstream was good pointer and your UPDATE is about as far as we will probably get without writing some hugely massive convoluted mess, for now I think I'll just write to a file and hopefully I won't need the printf output for many tests.
-
Martze over 9 yearsWorks well, but if i use multiple unit tests, some fail with an exception because the buffer is already freed and stdout is written into it. In case of only a temporarly redirection into the buffer use a
setbuf(stdout, NULL);
at the end of the usage. -
rraallvv over 8 yearsI want to suppress the console output entirely, keeping just the captured buffer is it possible?
-
sigy over 7 yearsSee this answer to avoid the "NUL"-Hack on POSIX systems: stackoverflow.com/a/19499003/1557062