我正在写一些来自stdin的C99代码:
// [...]
fgets(buf, sizeof(buf), stdin);
// [...]
但我想知道在这种情况下是否应该捕获错误,因为shell可以将stdin
重定向到可能不如普通stdin
强大的任何内容。但这也意味着必须检查stdin
,stdout
和stderr
上的每次访问是否存在错误,我很少在printf
和co之后看到任何检查。 / p>
那么,是否建议检查每个流访问是否存在错误?
上面的例子就像是:
// [...]
if (!fgets(buf, sizeof(buf), stdin) && ferror(stdin)) {
exit(EXIT_FAILURE);
}
// [...]
提前致谢!
答案 0 :(得分:3)
每次使用时,您都必须检查fgets()
的返回值。如果不这样做,您不知道缓冲区中是否有有用的数据;它可以第二次保持最后一行。类似的评论适用于每个读操作;你必须检查读操作是否返回了你的预期。
if (fgets(buf, sizeof(buf), stdin) == 0)
...EOF, or some error...
在处理代码中,您需要决定要做什么。您可以在该代码中合法使用feof()
和ferror()
。对问题的正确反应取决于您的代码。检测EOF通常是退出循环或退出函数的原因(break
或return
,但只有在函数未打开文件时才返回;否则您必须至少关闭文件) 。检测stdin
上的错误将是罕见的;你将不得不决定做什么。
在写入stderr
或stdout
时检测错误是不常做的事情,但可以说是松散编程以省略它们。一个问题,特别是问题是stderr
,是“你将如何报告错误?”您可能需要使用syslog()
,但这是您必须考虑的问题。
答案 1 :(得分:1)
这取决于您正在开发的应用程序的性质。例如,如果您正在开发一个硬实时系统,其异常终止会导致严重问题。那么你应该采取预防措施来处理各种数据流错误。在这种情况下,请使用以下代码
if (!fgets(buf, sizeof(buf), stdin) && ferror(stdin)) {
exit(EXIT_FAILURE);
}
或类似的一些构造。但是,如果您的应用程序的罕见故障不会产生任何严重后果,则无需检查每个数据流操作。
答案 2 :(得分:0)
这是一个有趣的练习。找到某人的交互式程序,运行它直到它要求终端输入,然后按control-D(EOF)。可能性是作者没有检查feof(stdin)并且他的gets()调用只返回0字节,代码将其解释为空行。如果将其视为无效输入并重新提示,则它将以无限循环结束!