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 << ..
and printf
. 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?
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.
You can use freopen(..., stdout)
and then dump the file into memory or a std::string
.
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.
Try sprintf, that's more efficient.
int i;
char str[] = "asdf";
char output[256];
sprintf(output, "asdfasdf %s %d\n", str, i);