试图理解 fgets()

Trying to Understand fgets()

我正在编写一个程序来逐行读取文件。我知道 fgets() 会读到一个新行、n-1 个字符或 EOF。令我困惑的是 fgets() 是如何知道前进到文件中的新 line/where?

为了更清楚,我知道在 Java 中你必须明确告诉扫描仪读取下一行。但是在 C 语言中,我只是将 fgets() 放在一个 while 循环中并相信它正在完成它的工作。

我如何从逻辑上保证 fgets() 实际上正在前进到下一行,而不是在那个 while 循环中一遍又一遍地读取同一行(是的,我知道我可以打印出来)?

fgets() 的语义非常简单:从 FILE* 流指针读取字节,直到:

  • 目标数组已满(n-1 个字节已读取并存储到其中)。
  • 从流中读取了换行符并将其存储到目标数组中。
  • 已到达文件末尾或发生读取错误(EOFfgetc() 调用或等价物 return 编辑。可以通过在 fgets() returns NULL.[= 之后调用 ferr() and/or feof() 来区分文件结束和读取错误条件。 58=]

空终止符总是在从流中读取字节后存储到数组中,除非立即到达文件末尾 (fgets() returns NULL) 或者如果缓冲区大小指定为大小为 0。

fgets() 的行为就好像使用 fgetc().

一次读取一个字节的流

fgets() 消耗从流中读取的字节并将它们存储到目标数组中。它不能再次读取相同的字节,除非您使用 rewind()fseek()fsetpos() 显式向后搜索流,如果流完全支持搜索。附加到常规文件的流通常支持搜索,但以文本模式打开的文件需要在某些系统上进行特定处理,尤其是 Microsoft Windows。另请注意,使用 ungetc() 推回流中的字节将在实际流中的任何字节之前被 fgets() 读取。

fgets() 如果该行足够短以适合空终止符之前的数组,则将换行符存储到目标数组中。

如果行超过目标数组中可用的 space,

fgets() 会将长行分成更小的块。处理长行很棘手且容易出错。请注意,当 fgets() 由于目标数组中缺少 space 而读取部分行时,对 fgets() 的下一次调用将继续从上一次调用停止点的同一行读取.

如果从 fgets() 开始 return,目标数组不以换行符结束,则发生以下情况之一:

  • 当前行太长,并且只从流中读取了适合数组的字节数。
  • 读取的行是文件中的最后一行,文件未以换行序列结束。
  • 从文件中读取了一个空字节。

对这些案例处理不当可能会导致潜在的未定义行为 and/or 可利用的缺陷。