在Windows上redirect标准输出/标准错误

我有一个Windows GUI应用程序,使用第三方库打印debugging/错误信息到标准输出/标准错误。 我find了许多解决scheme将它们redirect到我的日志文件。 但是,只有四分之一的人按预期工作。 我在WinXP SP3 32位上使用VS 2008 SP1。 我没有包含error handling,但没有调用返回错误。

// 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); 

在我testing了它们之后(当然是分开的),我得到了这些结果:
3testing打印到cout!
3testing打印到cerr!
4testingprintf到cout!
4testing打印到cout!
4testingprintf到cerr!
4testing打印到cerr!

为什么只有最后一个解决scheme完全工作? 使用它安全吗?

更新。 XCodetesting结果:
2testingprintf到cout!
2testing打印到cout!
2testingprintf到cerr!
2testing打印到cerr!
4testingprintf到cout!
4testing打印到cout!
4testingprintf到cerr!
4testing打印到cerr!
第一个显然只有Windows,第三个失败,因为没有带FILE *参数的文件stream构造函数。

从最后:

  1. 你正在改变实际的FILE 指针到标准输出和标准错误。 明显的原因是什么。 std :: cout和std :: cerr最终将输出发送到这些指针。
  1. std :: ios.rdbuf更改std :: ios实例(在本例中为std :: cout和std :: cerr)发送它的流的流。
  1. 我从来没有听说过。 我可以做一些研究并编辑答案。
  1. 和2一样。