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



在查看fgets§7.21.7.2, 3 的 ISO C11 标准时,返回值是关于概要代码的

#include <stdio.h>
char *fgets(char* restrict s, int n, FILE* restrict stream);

如果成功,fgets函数将返回s。如果遇到文件结尾,并且没有字符读入数组,则数组的内容保持不变,并返回空指针。如果在操作过程中发生读取错误,则数组内容不确定,并返回空指针。

该标准规定,为文件结尾返回空指针,并且没有读入任何字符或发生读取错误。我的问题是,仅从fgets和返回的 null 指针来看,有没有办法区分这两种情况中的哪一种导致了错误?

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

是的,使用feof()ferror()来区分。 @Nothing 什么都没有


然而,正确使用很重要。 考虑两个代码:

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";
}

第二个正确地测试了针对NULL的返回值,如OP所建议的那样。

第一个可能会遇到一个罕见的问题。ferror(stream)测试标志。此标志可能是由先前stream的 I/O 函数调用设置的,因此此fgets()不一定是导致错误的原因。 最好检查fgets()的结果,看看这个函数是否失败。

如果代码要在检测到错误后继续使用stream,请确保在继续之前清除错误 - 例如尝试重试。

if (ferror(stream)) {   
clearerr(stream);
return "Input error occurred");
}

请注意,clearerr()会清除错误和文件结束标志。

这同样适用于feof(),但大多数代码都是为了在文件结尾为真后退出使用stream


有第三种病理方法来接收NULLfeof()ferror()都不会返回NULL如 fgets(( 返回带有短缓冲区的 NULL 是否兼容?中所述。 仔细阅读 C 规范有 3 个"如果",其中可能不是真的,因为缺少规范 - 这意味着 UB。

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

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

从本网站

相关内容

  • 没有找到相关文章

最新更新