在stdin,stdout,stderr上捕获错误

时间:2013-05-16 19:09:37

标签: c stream stdout stdin stderr

我正在写一些来自stdin的C99代码:

// [...]
fgets(buf, sizeof(buf), stdin);
// [...]

但我想知道在这种情况下是否应该捕获错误,因为shell可以将stdin重定向到可能不如普通stdin强大的任何内容。但这也意味着必须检查stdinstdoutstderr上的每次访问是否存在错误,我很少在printf和co之后看到任何检查。 / p>

那么,是否建议检查每个流访问是否存在错误?

上面的例子就像是:

// [...]
if (!fgets(buf, sizeof(buf), stdin) && ferror(stdin)) {
    exit(EXIT_FAILURE);
}
// [...]

提前致谢!

3 个答案:

答案 0 :(得分:3)

每次使用时,您都必须检查fgets()的返回值。如果不这样做,您不知道缓冲区中是否有有用的数据;它可以第二次保持最后一行。类似的评论适用于每个读操作;你必须检查读操作是否返回了你的预期。

if (fgets(buf, sizeof(buf), stdin) == 0)
    ...EOF, or some error...

在处理代码中,您需要决定要做什么。您可以在该代码中合法使用feof()ferror()。对问题的正确反应取决于您的代码。检测EOF通常是退出循环或退出函数的原因(breakreturn,但只有在函数未打开文件时才返回;否则您必须至少关闭文件) 。检测stdin上的错误将是罕见的;你将不得不决定做什么。

在写入stderrstdout时检测错误是不常做的事情,但可以说是松散编程以省略它们。一个问题,特别是问题是stderr,是“你将如何报告错误?”您可能需要使用syslog(),但这是您必须考虑的问题。

答案 1 :(得分:1)

这取决于您正在开发的应用程序的性质。例如,如果您正在开发一个硬实时系统,其异常终止会导致严重问题。那么你应该采取预防措施来处理各种数据流错误。在这种情况下,请使用以下代码

if (!fgets(buf, sizeof(buf), stdin) && ferror(stdin)) {
    exit(EXIT_FAILURE);
}

或类似的一些构造。但是,如果您的应用程序的罕见故障不会产生任何严重后果,则无需检查每个数据流操作。

答案 2 :(得分:0)

这是一个有趣的练习。找到某人的交互式程序,运行它直到它要求终端输入,然后按control-D(EOF)。可能性是作者没有检查feof(stdin)并且他的gets()调用只返回0字节,代码将其解释为空行。如果将其视为无效输入并重新提示,则它将以无限循环结束!

相关问题