C标准:fgets返回非NULL但遇EOF时,feof是否必定返回true?
fgets读取部分内容遇EOF时feof的行为疑问
先看这段代码:
while (fgets(s, sizeof(s), f) != NULL) { if (feof(f)) { break; } }
问题场景
调用fgets时已将一个或多个字符读取到s中,但因遇到文件结束符(EOF)而停止读取。根据C标准,这种情况下fgets不会返回空指针,循环体将执行。请问在此迭代中,C标准是否保证feof会返回true?另外我一直认为应仅在I/O函数的返回值明确指示失败时,才调用feof(以及ferror)。
解答
C标准明确保证此时feof(f)会返回true。
根据C标准对fgets的规范:当fgets成功读取至少一个字符,但在达到指定读取长度前遇到EOF时,它会把已读取的字符存入目标缓冲区s,自动追加字符串终止符'\0',同时会设置该文件流的EOF标志位。而feof函数的核心作用就是检测流的EOF标志位是否被置位,所以此时调用feof(f)必然返回非零值(即布尔意义上的true)。
你提到的“仅在I/O函数返回值指示失败时调用feof/ferror”是正确的编程最佳实践,但这个场景属于特殊情况:fgets返回非NULL表示读取到了有效内容,但确实因为EOF提前终止了读取操作,此时调用feof是合理的,用来区分“读满缓冲区”和“遇EOF提前结束”这两种不同的成功读取场景。
内容的提问来源于stack exchange,提问作者emron
相关产品推荐
相关产品推荐

