前言
在不同类型的应用程序中,标准输出(stdout)和标准错误(stderr)流的处理方式可能会有所不同。特别是在图形用户界面(GUI)应用程序、后台进程或服务中,这些应用程序可能没有直接的控制台窗口来显示这些输出,所以我们经常会遇到代码中用了printf
或std::cout
,却无法看到它们的输出信息。
一、输出信息去了哪里?
printf
或 std::cout
输出的信息会被发送到程序的默认输出流,这取决于程序运行的环境:
- 控制台应用程序:即在命令行窗口中运行,输出信息将显示在启动该程序的命令行窗口中。这是最常见的情况,
stdout
和stderr
默认指向控制台窗口 - 图形用户界面(GUI)应用程序:比如 Windows 的 .exe 文件,并且没有创建或重定向控制台窗口,
stdout
和stderr
的输出将不会显示在用户界面上,它们会被丢弃或不显示 - 服务或后台进程:标准输出和标准错误通常不会显示在用户可见的控制台中,这些输出可能会被丢弃
二、重定向输出
1.输出到控制台
代码如下:
#include <windows.h>
#include <cstdio>
int main() {
// 分配一个新的控制台窗口
AllocConsole();
// 重新分配标准输出和标准错误流
FILE* new_stdout;
FILE* new_stderr;
// 打开控制台用于标准输出
if (freopen_s(&new_stdout, "CONOUT$", "w", stdout) != 0) {
// 如果打开失败,打印错误信息到标准错误
fprintf(stderr, "Failed to redirect stdout.\n");
return 1;
}
// 打开控制台用于标准错误
if (freopen_s(&new_stderr, "CONOUT$", "w", stderr) != 0) {
// 如果打开失败,打印错误信息到标准错误
fprintf(stderr, "Failed to redirect stderr.\n");
return 1;
}
// 现在可以使用 stdout 和 stderr 输出到控制台窗口了
printf("This is a test message to stdout.\n");
fprintf(stderr, "This is a test message to stderr.\n");
return 0;
}
这段代码的作用是确保程序在运行时能够显示输出信息和错误信息,即使程序原本没有控制台窗口。通过分配一个新的控制台窗口并将 stdout
和 stderr
重新定向到这个控制台窗口,程序可以将输出信息直接显示在控制台上。
2.输出到文件
代码如下:
#include <cstdio>
int main() {
FILE* file = fopen("output.log", "w");
if (file) {
// 重新定向 stdout 和 stderr 到文件
freopen_s(&file, "output.log", "w", stdout);
freopen_s(&file, "output.log", "w", stderr);
printf("This is a test message to stdout.\n");
fprintf(stderr, "This is a test message to stderr.\n");
fclose(file); // 记得关闭文件
} else {
fprintf(stderr, "Failed to open log file.\n");
}
return 0;
}
如果上述代码无法实现,可以试一下下面这种写法:
int main() {
FILE *new_stdout;
FILE *new_stderr;
freopen_s(&new_stdout, "output.txt", "w", stdout);
freopen_s(&new_stderr, "output.txt", "w", stderr);
return 0;
}
在这个示例中,stdout
和 stderr
的输出将被写入到 output.log 文件中,而不是默认的控制台或命令行窗口。
三、关于 OutputDebugString
OutputDebugString
和 printf/std::cout
都是用于输出调试信息的工具,但它们有不同的用途和行为。下面是它们之间的主要区别:
- 用途:
OutputDebugString
是 Windows API 的一部分,用于将调试字符串发送到调试器,例如 Visual Studio 的“输出”窗口。printf
和std::cout
用于将文本输出到标准输出流,通常是终端或命令行窗口 - 特性:
OutputDebugString
输出不会显示在标准控制台窗口中,而是发送到调试器,因此不会影响终端或命令行输出,只适用于 Windows 平台。printf/std::cout
输出会显示在控制台窗口中,会影响终端显示,在大多数平台上可用,包括 Windows、Linux 和 macOS