Redirecting stdout / stderr on Windows

I have a Windows GUI application that uses third party libraries that print debug / error information to stdout / stderr. I have found many solutions to redirect them to a log file. But only 1.5 out of 4 work as expected. I am using VS 2008 SP1 on WinXP SP3 32-bit. I did not enable error handling, but no calls returned any errors.

// First one:
SetStdHandle(STD_OUTPUT_HANDLE, (HANDLE)_get_osfhandle(_fileno(log_file.get_FILE())));
SetStdHandle(STD_ERROR_HANDLE, (HANDLE)_get_osfhandle(_fileno(log_file.get_FILE())));

printf("%s", "1 Test printf to cout!\n");
fprintf(stderr, "%s", "1 Test printf to cerr!\n");

std::cout << "1 Test print to cout!\n";
std::cerr << "1 Test print to cerr!\n";

fflush(stdout);
fflush(stderr);


// Second one:
_dup2(_fileno(log_file.get_FILE()), _fileno(stdout));
_dup2(_fileno(log_file.get_FILE()), _fileno(stderr));

printf("%s", "2 Test printf to cout!\n");
fprintf(stderr, "%s", "2 Test printf to cerr!\n");

std::cout << "2 Test print to cout!\n";
std::cerr << "2 Test print to cerr!\n";

fflush(stdout);
fflush(stderr);


// Third one:
std::ofstream out_stream(log_file.get_FILE());
std::cout.rdbuf(out_stream.rdbuf());
std::cerr.rdbuf(out_stream.rdbuf());

printf("%s", "3 Test printf to cout!\n");
fprintf(stderr, "%s", "3 Test printf to cerr!\n");

std::cout << "3 Test print to cout!\n";
std::cerr << "3 Test print to cerr!\n";

fflush(stdout);
fflush(stderr);


// Fourth one:
*stdout = *log_file.get_FILE();
*stderr = *log_file.get_FILE();

printf("%s", "4 Test printf to cout!\n");
fprintf(stderr, "%s", "4 Test printf to cerr!\n");

std::cout << "4 Test print to cout!\n";
std::cerr << "4 Test print to cerr!\n";

fflush(stdout);
fflush(stderr);

      

After I tested them (separately of course), I got the following results:
3 Test print in cout!
3 Test print in cerr!
4 Test printf on cout!
4 Test print in cout!
4 Checking print on cerr!
4 Test print in cerr!

Why only the last solution works completely? Is it safe to use?

Update. Xcode test results:
2 printf test on cout!
2 Test print in cout!
2 Test printf on cerr!
2 Test print in cerr!
4 Test printf on cout!
4 Test print in cout!
4 Checking print on cerr!
4 Test print in cerr!
The first one is obviously Windows-only, while the third is due to the lack of a file stream constructor that takes a FILE * parameter.

+3


source to share


1 answer


From the end:

  1. You are changing the actual FILE

    pointer to stdout and stderr. It's obvious why this works. std :: cout and std :: cerr end up sending the output to these pointers.

  1. std :: ios.rdbuf changes the stream where the std :: ios instance (in this case std :: cout and std :: cerr) send the stream.


  1. I've never heard of this. I can research a bit and edit the answer.

  • Same as 2.
0


source







All Articles