我什么时候应该使用perror(“…”)和fprintf(stderr,“…”)?


105

阅读手册页和一些代码并不能真正帮助我理解-或更好的区别-当我应该使用- perror("...")或时fprintf(stderr, "...")

Answers:


113

调用perror将为您提供的解释值errno,这是POSIX系统调用写入的线程局部错误值(即,每个线程都有其自己的值errno)。例如,如果您对进行了调用open(),并且生成了错误(即返回-1),则可以在此后perror立即调用以查看实际错误是什么。请记住,如果在此期间调用其他syscall,则in的值errno将被覆盖,并且perror如果较早的syscall生成了错误,则调用对于诊断问题将没有任何用处。

fprintf(stderr, ...)另一方面,可用于打印您自己的自定义错误消息。通过打印到stderr,可以避免将错误报告输出与应发送到的“常规”输出混合stdout

请记住,这fprintf(stderr, "%s\n", strerror(errno))与相似,perror(NULL)因为对的调用strerror(errno)将为生成打印的字符串值errno,然后可以通过将其与任何其他自定义错误消息合并fprintf


3
哦,知道了。perror函数的工作方式取决于errno的值。If you use a function that effects errno then it makes sense to use perror如果使用的函数不会影响errno并仅返回错误代码,则应使用fprintf(stderr,fmt,...)。例如,如果字符串超出范围,strtol将返回LONG_MAX或LONG_MIN并将errno设置为ERANGE。因此,如果由于超出范围而导致strtol失败,我将使用perror。
freeboy1015 2012年

6
一个细节strerror不需要是线程安全的。这很愚蠢,但这是标准。strerror_l可以用作POSIX 2008系统上的替代产品。strerror_r也可以在较旧的系统上使用,但对于某些版本不一致的系统,确实存在令人讨厌的问题。
R .. GitHub STOP HELPING ICE

还是作为nitpick,我想在末尾perror加上'\n',这样的格式将是"%s\n",不是吗?
詹斯·古斯特

1
@R ..,哈,我已经有了,据我所知他们没有付我钱。而且由于MS似乎完全削减了对C的支持,最后我将是唯一的一个:) strerror_s实际上作为接口不是太差。
詹斯·古斯特

2
完全削减支持?好像他们又骗了委员会。_s基本上,将他们的垃圾纳入标准是MS的游戏(“如果采用我们的界面,我们将考虑实际上使我们的产品支持您的标准。”)当然,现在他们并没有遵循。实际上,我同意这个界面本身并不坏。不好的是,宣传(以编译器警告的形式),大多数标准库都是“不安全的”,_s应该使用整个函数家族而不是标准函数。
R .. GitHub停止帮助ICE

40

他们做的事情完全不同。

您可以使用perror()来打印stderr与相对应的消息errno。您可以fprintf()任何内容打印到stderr或任何其他流。perror()是非常专业的打印功能:

perror(str);

相当于

if (str)
    fprintf(stderr, "%s: %s\n", str, strerror(errno));
else
    fprintf(stderr, "%s\n", strerror(errno));

12

perror(const char *s):打印您提供的字符串,后跟描述的当前值的字符串errno

stderr:这是用于将您自己的错误消息传递到的输出流(默认为终端)。

相关:

char *strerror(int errnum):给它一个错误号,它将返回相关的错误字符串。


2

perror()总是写到stderr; 与fprintf()一起使用的strerr()可以写入任何输出-包括stderr,但不仅限于此。

fprintf(stdout, "Error: %s", strerror(errno));
fprintf(stderr, "Error: %s", strerror(errno)); // which is equivalent to perror("Error")

此外,perror施加了自己的文本格式“ text:error description”


-2

Perror函数需要花费更多时间来执行从用户空间到内核空间的执行调用,而fprintf调用却从api到内核

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.