我什么时候应该使用perror("...")和fprintf(stderr,"......")?

fre*_*015 97 c stderr

阅读手册页和一些代码并没有真正帮助我理解它们之间的区别 - 或者更好,当我应该使用 - perror("...")或者fprintf(stderr, "...").

Jas*_*son 102

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

fprintf(stderr, ...)另一方面,可用于打印您自己的自定义错误消息.通过打印stderr,可以避免错误报告输出与应该转到的"正常"输出混合stdout.

请记住,这fprintf(stderr, "%s\n", strerror(errno))类似于perror(NULL)自调用以来strerror(errno)将生成打印的字符串值errno,然后您可以将其与任何其他自定义错误消息组合起来fprintf.

  • 一个细节,`strerror`不需要是线程安全的.这是愚蠢的,但这是标准.可以使用`strerror_l`作为POSIX 2008系统的直接替代品.`strerror_r`也适用于较旧的系统,但是对于某些具有不一致版本的系统而言,它确实存在令人讨厌的问题. (6认同)
  • 哦,得到它.perror函数的工作方式取决于errno的值.`如果使用影响errno的函数,则使用perror是有意义的.如果使用的函数不会影响errno并且只返回错误代码,则应使用fprintf(stderr,fmt,...).例如,如果字符串超出范围并且将errno设置为ERANGE,则strtol将返回LONG_MAX或LONG_MIN.因此,如果strtol因超出范围而失败,我会使用perror. (3认同)
  • 切割支持完全?看起来他们又愚弄了委员会.让他们的`_s`垃圾成为标准基本上是MS的游戏("如果你采用我们的界面,我们会考虑实际上让我们的产品支持你的标准.")当然,现在他们没有完成.实际上我同意这个界面本身并不坏.什么是坏的是宣传(以编译器警告的形式),大多数标准库是"不安全的",并且应该使用整个`_s`函数系列而不是标准函数. (2认同)

fre*_*015 37

他们做了不同的事情.

perror()用来打印stderr对应的消息errno.您可以使用fprintf()打印任何东西stderr,或任何其他流.perror()是一个非常专业的打印功能:

perror(str);
Run Code Online (Sandbox Code Playgroud)

相当于

if (str)
    fprintf(stderr, "%s: %s\n", str, strerror(errno));
else
    fprintf(stderr, "%s\n", strerror(errno));
Run Code Online (Sandbox Code Playgroud)


Adi*_*dib 11

perror(const char *s):打印您给它的字符串,后跟一个描述当前值的字符串errno.

stderr:它是一个输出流,用于将您自己的错误消息传递给(默认为终端).

相关:

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