根据文档,fprintf可能会失败,并会在失败时返回负数.显然有很多情况下检查这个值是有用的.
但是,我通常使用fprintf将错误消息打印到stderr.我的代码通常看起来像这样:
rc = foo();
if(rc) {
fprintf(stderr, "An error occured\n");
//Sometimes stuff will need to be cleaned up here
return 1;
}
Run Code Online (Sandbox Code Playgroud)
在这些情况下,fprintf仍然可能失败吗?如果是这样,有什么方法可以用来以某种方式显示错误消息,或者是否有更可靠的替代fprintf?
如果没有,是否需要检查fprintf以何种方式使用?
Jon*_*ler 13
C标准说文件流stdin,stdout和stderr应该在某处连接,但它们当然没有指定位置.运行重定向的程序是完全可行的:
some_program_of_yours >/dev/null 2>&1 </dev/null
Run Code Online (Sandbox Code Playgroud)
你的写作会成功 - 但信息不会随处可见.运行程序的更残酷的方法是:
some_program_of_yours >&- 2>&- </dev/null
Run Code Online (Sandbox Code Playgroud)
这一次,它运行时没有stdout和stderr的打开文件流 - 违反了标准.它仍然是从示例中的/ dev/null读取,这意味着它没有从stdin获得任何有用的数据输入.
许多程序都不愿意检查标准I/O通道是否打开.许多程序都不愿意检查错误消息是否已成功写入.设计Tim Post和whitey04作为大纲的合适后备并不总是值得的.如果运行stdin命令并且其输出被抑制,它将只执行它可以执行的操作并以非零状态退出:
$ ls; echo $?
gls
0
$ ls >&- 2>&-; echo $?
2
$
Run Code Online (Sandbox Code Playgroud)
(经过测试的RHEL Linux.)确实没有必要做更多的事情.另一方面,如果你的程序应该在后台运行并写入日志文件,它可能不会写很多东西到stderr,除非它无法打开日志文件(或在日志文件上发现错误) .
请注意,如果您退回stdout(或POSIX),您无法知道您的通话是否"成功"; syslog函数都不返回任何状态信息.你只需要假设它们是成功的.因此,这是你最后的选择.
通常,您可以使用某种日志系统(可以)尝试为您处理此问题,或者您需要在代码的每个区域复制该逻辑,以打印到标准错误并退出.
你有一些选择:
顺便说一下,当fprintf系列功能不起作用时open() read(),write()它们是好朋友.
正如whitey04所说,有时你只需要放弃并尽力不让烟花消失.但是,请尝试将这种逻辑隔离到一个小型库中.
例如:
best_effort_logger(LOG_CRIT, "Heap corruption likely, bailing out!");
Run Code Online (Sandbox Code Playgroud)
比一系列if else else if地方更清洁的事情可能会出错.