在C中,默认情况下stdout
和stderr
都打印到控制台窗口。除了缓冲级别,stderr
和stdout
之间是否有其他区别?
如果从控制台,通过批处理文件或快捷方式运行程序,请使用>或1>将stdout重定向到文件,并使用2>将stderr重定向到文件。例如,如果从stdin读取并同时写入stdout和stderr:
myprog <input.txt >output.txt 2>error.txt
或者如果您希望将stdout输出到文件,但在屏幕上显示stderr,请使用:
myprog <input.txt >output.txt
stdout
和stderr
之间的差异之一是缓冲级别。在§7.21.3 Files ¶7中,C11标准说:
在程序启动时,预定义了三个文本流,无需显式打开它们-标准输入(用于读取常规输入),标准输出(用于写入常规输出)和标准错误(用于写入诊断输出)。最初打开时,标准错误流未完全缓冲;当且仅当可以确定该流不引用交互式设备时,标准输入和标准输出流才被完全缓冲。
通常,这意味着标准输出是行缓冲的(因此,当打印换行符或缓冲区已满时,将刷新数据),而标准错误是行缓冲的或未缓冲的。这些特征当然可以更改。
标准错误流的目的是将错误消息与常规输出分开。这在诸如shell脚本之类的上下文中很重要,在该上下文中,标准输出可能会发送到管道或文件。重定向使标准错误仍然流向其他地方-通常是终端。您也可以与标准错误分开捕获标准输出,至少在外壳足够强大的情况下。
program > file
program | filter
program 2> error.log | filter
program > file 2> error.log
program 2> error.log
前两个使错误消息在终端上可见。最后三个捕获文件error.log
中的错误消息-将标准输出分别发送到filter
程序,file
或终端窗口。
通过将错误消息与标准输出分离,流水线下的程序(在我的示例中为filter
)不必解释来自program
的错误消息,这使它们变得非常简单。
stderr
是-好吧-错误的地方。这真的很有用。像make
一样-如果程序的返回码不为0(错误完成),它将打印stderr
。用户无法将stderr
与stdout
区别开来,但仍然是建议的错误位置。但是,如果您的程序将由任何自动化程序,shell脚本等运行,则可以用来跟踪错误,并且always使用它。