views:

1914

answers:

3

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?

+7  A: 

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 setbuf for more info.

Gabe
Accepted 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.
thelsdj
+2  A: 

You can use freopen(..., stdout) and then dump the file into memory or a std::string.

MSN
I would really like to skip having to use the filesystem. Something that only uses ram would be best.
thelsdj
At that point then you have to hit the operating system.
MSN
+1  A: 

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.

cvsdave
IOFBF of _IOFBF? I had to use the latter to get this working
Gayan