为什么我们在从printf打印自定义错误消息时使用stderr工作正常?
例如,为什么我可以写一个这样的语句时使用stderr:
printf("error! you didn't... blah blah blah");
答案 0 :(得分:13)
stderr
代表标准错误流。
在控制台编程中,它是控制台 - 屏幕。它与stdout
基本相同。
一般做法是将所有错误消息重定向到stderr
,将所有常规输出重定向到stdout
。
原因是可以将标准输出重定向到文件而不是屏幕。因此,如果在命令提示符下执行dir > dirlist.txt
命令,则目录列表将进入文本文件而不是屏幕。如果您将错误消息重定向到stderr
,则错误将始终转到屏幕而不是文件,以便可以立即向用户发出警告,而不是最终在文件中看到意外结果。
使用printf()
会向控制台显示错误消息,该错误消息将存储在stdout
缓冲区中,但使用stderr
,则会有所不同
stderr
可以用作任何函数的参数,该函数接受类型为FILE *的参数,期望输出流,如fputs
或fprintf
。
虽然在许多情况下stdout
和stderr
都与同一输出设备(如控制台)相关联,但应用程序可以区分发送到stdout的内容和stderr的内容。他们被重定向。例如,经常将控制台程序(stdout
)的常规输出重定向到文件,同时期望错误消息一直显示在控制台中。
还可以使用freopen
函数将stderr重定向到程序中的其他目的地。
stderr
在启动时永远不会完全缓冲。它是依赖于库的,无论流是行缓冲还是默认缓冲(参见setvbuf)。
答案 1 :(得分:11)
最好将所有错误消息重定向到stderr
,同时将常规输出定向到stdout
。执行此操作是有益的,因为写入stderr
的任何内容都不会被缓冲,即,它会立即写入屏幕,以便可以立即向用户发出警告。
答案 2 :(得分:7)
这是一个很好的做法。
让我们说你使用linux。如果是这样,您可以按照以下方式运行程序:
./ program> out 2> errout
'out'文件仅包含STDOUT 'errout'文件只包含STDERR
因此,如果您的输出长达数百行,则更容易在'errout'中查找少量错误,而不是查看大量非错误行和错误行。
答案 3 :(得分:1)
除了stderr
没有缓冲之外,将输出分成错误与正常输出也很好,以便其他程序更容易使用您的程序。这样,调用程序可以根据需要知道的内容选择性地重定向标准或错误输出。同样的工具可以通过Unix shell手动使用 - 这是我有时使用的一种方式:
% find / -iname hello.txt
find: /.DocumentRevisions-V100: Permission denied
find: /.fseventsd: Permission denied
find: /.MobileBackups: Permission denied
find: /.Spotlight-V100: Permission denied
find: /.Trashes: Permission denied
^C
% find / -iname hello.txt 2>/dev/null <-- filter "Permission denied" errors
答案 4 :(得分:0)
如果您将程序的输出重定向到文件中,您仍然希望在屏幕上看到错误。