在查看fgets§7.21.7.2,3 的ISO C11标准时,会根据概要代码说明返回值:
#include <stdio.h>
char *fgets(char* restrict s, int n, FILE* restrict stream);
Run Code Online (Sandbox Code Playgroud)
如果成功,fgets函数返回s.如果遇到文件结尾且没有字符读入数组,则数组的内容保持不变,并返回空指针.如果在操作期间发生读取错误,则数组内容是不确定的,并返回空指针.
该标准表示为eof返回空指针,并且没有读入任何字符或发生读取错误.我的问题是,只是来自fgets和返回的空指针,是否有办法区分导致错误的两种情况中的哪一种?
有没有办法区分导致错误的两种情况中的哪一种?
是的,使用feof()和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";
}
Run Code Online (Sandbox Code Playgroud)
第二个正确测试返回值NULL,如OP所建议的那样.
第一个可以遇到一个罕见的问题.该ferror(stream)测试的标志.此标志可能已由先前的 I/O函数调用设置,stream因此这fgets()不一定是错误的原因.最好检查结果,fgets()看看这个功能是否失败.
如果stream在检测到错误后要继续使用代码,请务必在继续之前清除错误 - 例如尝试重试.
if (ferror(stream)) {
clearerr(stream);
return "Input error occurred");
}
Run Code Online (Sandbox Code Playgroud)
请注意,clearerr()清除错误和文件结束标志.
这同样适用feof(),但是stream一旦文件结束为真,大多数代码都会被写入以退出.
有一种第三种病理学方法可以接收,NULL并且既feof()没有ferror()返回,也不会NULL像Is fgets()中的详细信息那样返回NULL并且符合短缓冲区?.仔细阅读C规范有3个"ifs",其中有可能不是这样,因为缺乏规范 - 这意味着UB.