是否可以区分fgets返回的错误

Mik*_*t25 8 c fgets

在查看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和返回的空指针,是否有办法区分导致错误的两种情况中的哪一种?

Not*_*ing 8

如果故障是由文件结束条件引起的,则另外设置eof指示符(参见feof()).在这种情况下,str指向的数组的内容不会改变.如果失败是由其他一些错误引起的,请设置错误指示符(请参阅ferror()).str指向的数组的内容是不确定的(甚至可能不是以null结尾).

因此,您需要检查feof()ferror()确定错误.

来自这个网站


chu*_*ica 6

有没有办法区分导致错误的两种情况中的哪一种?

是的,使用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()返回,也不会NULLIs fgets()中的详细信息那样返回NULL并且符合短缓冲区?.仔细阅读C规范有3个"ifs",其中有可能不是这样,因为缺乏规范 - 这意味着UB.