0

我正在写一些从标准输入读取的 C99 代码:

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

但是我想知道在这种情况下是否应该捕获错误,因为 shell 可以重定向stdin到任何可能不如 plain 健壮的东西stdin。但这也意味着,每次访问stdin,stdoutstderr都必须检查错误,而且我很少看到printf和 co 之后的任何检查。

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

上面的示例将类似于:

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

提前致谢!

4

3 回答 3

3

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

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

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

检测写入stderr或写入时的错误stdout是不常做的事情,但忽略它们可以说是草率的编程。一个问题,特别是如果它stderr有问题,是“你将如何报告错误?” 您可能需要syslog()改用,但这是您必须考虑的问题。

于 2013-05-16T19:46:32.380 回答
1

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

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

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

于 2013-05-16T19:23:57.877 回答
0

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

于 2013-05-16T19:49:52.750 回答