在查看fgets
§7.21.7.2,3的ISO C11标准后,会根据概要代码说明返回值:
#include <stdio.h>
char *fgets(char* restrict s, int n, FILE* restrict stream);
如果成功, fgets 函数会返回 s 。如果遇到文件结尾且没有字符读入数组,则数组的内容保持不变,并返回空指针。如果在操作期间发生读取错误,则数组内容不确定并返回空指针。
标准表示为eof返回空指针,并且没有读入任何字符或发生读取错误。我的问题是,仅从fgets
和返回的空指针,有没有办法区分这两种情况中的哪一种导致错误?
答案 0 :(得分:8)
如果失败是由文件结束条件引起的,则另外设置eof指示符(参见feof())。在这种情况下,str指向的数组的内容不会改变。 如果失败是由其他一些错误引起的,请设置错误指示符(请参阅ferror())。 str指向的数组内容是不确定的(甚至可能不会以null结尾)。
因此,您需要检查feof()
和ferror()
以确定错误。
答案 1 :(得分:6)
有没有办法区分导致错误的两种情况中的哪一种?
是的,请使用RetrieveUpdateDestroyAPIView
和feof()
进行区分。 @Nothing Nothing
然而正确使用非常重要。考虑两个代码:
ferror()
第二个正确地测试了char buf[100];
fgets(s, sizeof s, stream);
if (feof(stream)) return "End-of-file occurred";
if (ferror(stream)) return "Input error occurred";
if (fgets(s, sizeof s, stream) == NULL) {
if (feof(stream)) return "End-of-file occurred";
if (ferror(stream)) return "Input error occurred";
return "Should never get here";
}
的返回值,如OP所示。
第一个可以遇到一个罕见的问题。 NULL
测试一个标志。此标志可能是由ferror(stream)
上的先前 I / O函数调用设置的,因此stream
不一定是错误的原因。最好检查fgets()
的结果,看看此功能是否失败。
如果在检测到错误后代码要继续使用fgets()
,请务必在继续之前清除错误 - 例如尝试重试。
stream
请注意if (ferror(stream)) {
clearerr(stream);
return "Input error occurred");
}
清除错误和文件结束标志。
同样适用于clearerr()
,但是一旦文件结束为真,大多数代码都是使用feof()
编写的。
有第3种病态方法可以接收stream
,NULL
和feof()
都不会返回ferror()
,详见Is fgets() returning NULL with a short buffer compliant? 。仔细阅读C规范有3&#34; ifs&#34;,其中可能没有它们是真的,因为缺乏规范 - 这意味着UB。