Redirecting stdout and stderr

Started by
4 comments, last by lucky_monkey 19 years, 2 months ago
I'm trying to redirect stdout and stderr to a buffer in my program. I need to do this because a library i'm using writes directly to these. This is what I have at the moment:

#include <iostream>
#include <stdio.h>
#include <sstream>

int main()
{
	std::ostringstream Out;
	
	std::cout.rdbuf(Out.rdbuf());
	std::cerr.rdbuf(Out.rdbuf());

	std::cout << "out\n";//Written to Out
	std::cerr << "err\n";//Written to Out
	
	printf("Out");//Still written to the console
}

The other way I've tried was to use freope(), but that only seems to work with disk files, not buffers in memory. Also it would be nice to be able to redirect stderr and stdout to the same place. Does anyone have any idea how to do this?
Advertisement
I'd say this isn't worth it. Just get rid of printfs and use just cout/cin or deal with a disk file.

However, if you really want to do it, I think there is a way (at least for linux, this might have to be adapted a bit for windows)

Create an asynchronous pipe (not entirely sure this is possible, but I expect it is). 'dup2' to fd's 1 and 2, and close the original of that end. occasionally read from the other end into your stringstream. (main loop or use some asynchronous event notification mechanism)

I think that'll work, but I've never tried anything quite so crazy.
What you did is a buffer redirection: you said to cerr and cout that the stream they should use is Out. printf() do not uses streams.

If you want to redirect printf() output (and perror() output as well) then you try to master the pipe() system call :) There are plenty of examples around the net.

Regards,
Quote:Original post by C-Junkie
I'd say this isn't worth it. Just get rid of printfs and use just cout/cin or deal with a disk file.


Don't be so harsh on it. I like printf() better than cout/cin. I like formatting with it better.

I usually do fprintf(stderr, "") or fprintf(stdout, ""). I thought you had to do that if you wanted to redirect the streams somewhere else.
Quote:Original post by okonomiyaki
Quote:Original post by C-Junkie
I'd say this isn't worth it. Just get rid of printfs and use just cout/cin or deal with a disk file.

Don't be so harsh on it. I like printf() better than cout/cin. I like formatting with it better.

Prehaps you should take a look at The Boost Format library which offers similar syntax to printf, and is TYPESAFE, along with a lot of other nifty things. A couple basic examples:

cout << format("%1% is a big %2%.") % "Mike" % "asshat" << endl;std::string fps_string = str( format("FPS: %1%") % fps );


You can also use all your wonderful printf-style placeholders instead of the ordered ones (%1% %2% %3% etc), like %0.2f and all that jazz.
Quote:Original post by Nitage
I need to do this because a library i'm using writes directly to these.
Maybe he can't just replace the library...

This little example prog. might help [smile]
#include <stdlib.h>#include <stdio.h>#include <fcntl.h>#define STDOUT  1int main( int argc, char *argv[] ) {    int null = open( "NUL", O_RDWR );    int stdout_old = dup( STDOUT );    printf( "redirecting...\n" );    dup2( null, STDOUT );    close( null );    printf( "redirected!\n" );    dup2( stdout_old, STDOUT );    close( stdout_old );    printf( "directed back to stdout.\n");    system( "pause" );    return EXIT_SUCCESS;}

If you actually want to keep the input then replace the "NUL" with the name of a file to redirect it to.

This topic is closed to new replies.

Advertisement