C++ 在Windows上重定向stdout/stderr

C++ 在Windows上重定向stdout/stderr,c++,c,windows,stdout,stderr,C++,C,Windows,Stdout,Stderr,我有一个Windows GUI应用程序,它使用第三方库将调试/错误信息打印到stdout/stderr。我找到了许多将它们重定向到日志文件的解决方案。但只有1.5%的工作符合预期。我在Win32 XP SP3 32位上使用VS 2008 SP1。我没有包括错误处理,但没有电话返回错误。 // First one: SetStdHandle(STD_OUTPUT_HANDLE, (HANDLE)_get_osfhandle(_fileno(log_file.get_FILE()))); SetS

我有一个Windows GUI应用程序,它使用第三方库将调试/错误信息打印到stdout/stderr。我找到了许多将它们重定向到日志文件的解决方案。但只有1.5%的工作符合预期。我在Win32 XP SP3 32位上使用VS 2008 SP1。我没有包括错误处理,但没有电话返回错误。

// 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);
//第一个:
SetStdHandle(标准输出句柄,(句柄)获取osfhandle(_fileno(log_file.get_file()));
SetStdHandle(标准错误句柄,(句柄)获取osfhandle(_fileno(log_file.get_file()));
printf(“%s”,“1个测试printf到cout!\n”);
fprintf(标准,“%s”,“1个测试打印到cerr!\n”);
std::cout从末尾开始:

  • 您正在将实际的
    文件更改为stdout和stderr。很明显,它为什么有效。std::cout和std::cerr最终将输出发送到这些指针
  • 更改std::ios实例(在本例中为std::cout和std::cerr)发送其流的流
  • 我从没听说过。我可能会做一些研究并编辑答案
  • 与2相同

  • 我怀疑:第一个设置了标准输出/错误句柄,但在标准库已经使用旧的句柄设置stdout/stderr之后。第二个可能不起作用,因为windows不使用文件描述符。第三个只适用于cout/cerr,因为您实际上没有对stdout/stderr做任何操作。最后一个是一个丑陋的不可移植的黑客。@immibis,解决方案是。。。?稍后将在OSX上测试其中3个。我没有解决方案,这也是我没有将其作为答案的一部分发布的原因之一。@immibis为什么你称最后一个为丑陋的不可移植黑客?丑陋是一个意见问题,我更感兴趣的是不可移植的部分。@Shark第四个部分正是stdout和stderr的重定向。如果不保存原始指针,原始指针永远不会被关闭或还原(无耻),但它们会被重定向。Markdown将您的数字重新格式化为4/5/6/7,而不是4/3/2/1。我猜您的意思是4-3-2-1:)好吧,我查看了stdout的定义,它看起来像这样
    \define stdout(&\u iob\u func()[1])
    ,所以我不确定第四种解决方案有多安全。@Sergi0这只是一个包含描述符(
    FILE
    指针)的数组。