是否可以区分fgets

时间:2017-07-23 04:33:23

标签: 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 。如果遇到文件结尾且没有字符读入数组,则数组的内容保持不变,并返回空指针。如果在操作期间发生读取错误,则数组内容不确定并返回空指针。

标准表示为eof返回空指针,并且没有读入任何字符或发生读取错误。我的问题是,仅从fgets和返回的空指针,有没有办法区分这两种情况中的哪一种导致错误?

2 个答案:

答案 0 :(得分:8)

  

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

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

来自this site

答案 1 :(得分:6)

  

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

是的,请使用RetrieveUpdateDestroyAPIViewfeof()进行区分。 @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种病态方法可以接收streamNULLfeof()都不会返回ferror(),详见Is fgets() returning NULL with a short buffer compliant? 。仔细阅读C规范有3&#34; ifs&#34;,其中可能没有它们是真的,因为缺乏规范 - 这意味着UB。