首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >perror()和printf()之间的区别

perror()和printf()之间的区别
EN

Stack Overflow用户
提问于 2015-12-05 09:00:23
回答 6查看 10.5K关注 0票数 6

我读过,perror()printf()都写在终端屏幕上。但是perror()stderrprintf()stdout。因此,要打印错误,为什么使用perror()printf()可以这样做。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2015-12-05 09:06:52

printf()不能写入stderrfprintf()可以。perror()总是这么做。

不需要向stdoutstderr写入到终端屏幕--这取决于实现(因为并非所有系统都有终端)。也不要求写入stdoutstderr会导致写入相同的设备(例如,一个可以重定向到文件,而另一个可以重定向到管道)。

perror()的实现将使用内置的错误代码含义的知识(由静态errno表示),标准库中的各种函数都使用它来报告错误情况。特定值的含义是实现定义的(即编译器和库之间的含义不同)。

票数 7
EN

Stack Overflow用户

发布于 2015-12-05 09:03:24

因为可能存在一些配置,您希望将stderr打印到控制台,但其他输出根本不打印(例如,删除冗长的内容)。在其他情况下,您可能需要重定向stderr以写入文件,这在生产中非常有用,而且该文件可用于了解远程计算机上发生的错误--您无法自己调试。

通常,您可以根据控制台输出的类型获得更多的控制权。

请参阅这个答案以了解如何在代码中进行流重定向。

或者,请参阅此链接关于如何强制流重定向以文件或忽略已编译程序上的流(同时在bash中调用它)。

票数 2
EN

Stack Overflow用户

发布于 2015-12-05 09:27:54

除了其他答案之外,您还可以在stderr上使用stderr,而在错误(3)上使用errno(3),如

代码语言:javascript
复制
 fprintf(stderr, "something wrong: %s\n", strerror(errno));

在GNU系统(许多Linux系统)上,您可以使用%m转换说明符来代替:

代码语言:javascript
复制
fprintf(stderr, "something wrong: %m\n");

按照惯例,您应该将错误消息输出到stderr (参见stderr(3));也可以参见syslog(3)来使用系统日志。

不要忘记用\n结束格式字符串,因为stderr通常是行缓冲的(但有时不是),或者使用弗卢什(3)

例如,您可能希望在fopen失败时同时显示错误、文件名和当前目录:

代码语言:javascript
复制
char* filename = somefilepath();
assert (filename != NULL);
FILE* f = fopen(filename, "r");
if (!f) {
   int e = errno; // keep errno, it could be later overwritten
   if (filename[0] == '/') /// absolute path
      fprintf(stderr, "failed to open %s : %s\n", filename, strerror(e));
   else { // we also try to show the current directory since relative path
      char dirbuf[128];
      memset (dirbuf, 0, sizeof(dirbuf));
      if (getcwd(dirbuf, sizeof(dirbuf)-1)) 
         fprintf(stderr, "failed to open %s in %s : %s\n", 
                 filename, dirbuf, sterror(e));
      else // unlikely case when getcwd failed so errno overwritten
         fprintf(stderr, "failed to open %s here : %s\n", 
                 filename, sterror(e));
   };
   exit(EXIT_FAILURE); // in all cases when fopen failed
 }

请记住,errno可能会被许多故障覆盖(因此我们将其存储在e中,在getcwd失败和覆盖errno的可能性不大的情况下)。

如果您的程序是一个deamon (例如已经调用了daemon(3)),那么最好使用系统日志(即调用daemon后调用openlog(3) ),因为daemon可以将stderr重定向到/dev/null

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34103091

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档