使用C语言中的fgets函数读取文本文件直到文件结尾

11

在C语言中,使用fgets正确读取文本文件直到EOF的方式是什么?我现在有这个(简化版):

char line[100 + 1];
while (fgets(line, sizeof(line), tsin) != NULL) { // tsin is FILE* input
   ... //doing stuff with line
}

具体来说,我在想是否应该将其他内容作为while条件?从文本文件解析到“行”的过程是否必须在while条件中执行?


解析应该在 while 循环中完成,或者你可以将每行存储到数组中,然后在 while 循环之后进行解析。完成后记得关闭文件。 - FreeStyle4
完全没问题,你甚至可以只写成 while (fgets(line, sizeof(line), tsin)) {...},让 fgets 的返回值作为测试条件即可。一个有效的指针会被判断为,而NULL则会被判断为 - David C. Rankin
我认为你做得对,关于省略!= NULL的回答并没有增加价值。 - AndersK
3个回答

10
根据参考文献,此函数成功时会返回 str。如果在读取字符时遇到文件结束符,则设置 eof指示器 (feof)。如果在读取任何字符之前就出现这种情况,则返回的指针是空指针 (str 的内容仍保持不变)。如果发生读取错误,则设置错误指示器 (ferror),并且还将返回一个空指针 (但是 str 指向的内容可能已发生更改)。因此,检查返回值是否为NULL即可。同时,解析进入 while循环体内。

4
你所做的是完全正确的,但你也可以简单地依赖于fgets的返回值作为测试本身,例如:
char line[100 + 1] = "";  /* initialize all to 0 ('\0') */

while (fgets(line, sizeof(line), tsin)) { /* tsin is FILE* input */
    /* ... doing stuff with line */
}

为什么要这样做呢?fgets会在成功时返回一个指向line的指针,或者在失败时(由于任何原因)返回NULL。有效的指针将测试为true,当然,NULL将测试为false
(注意:您必须确保line是在范围内声明的字符数组,以使用sizeof line作为长度。如果line只是指向数组的指针,则您只读取sizeof(char *)个字符)

我认为初始化所有line[]除了样式/调试之外没有太大的价值。你看到其他的价值吗? - chux - Reinstate Monica
除了一直试图向新的C程序员强调初始化所有变量的成本与不进行初始化时花费在调试上的时间相比非常小之外,这就是唯一的观点。 - David C. Rankin
你的代码暗示了 NULL 等于 0,但这并非在所有平台上都成立。 - AndersK
@AndersK. 你有没有一个while (fgets(...))会失败的平台示例?我很好奇,我还没有遇到过这种情况。 - David C. Rankin
@DavidC.Rankin 参见例如 https://dev59.com/FnE85IYBdhLWcg3w03Dz 但是确实,也许现在已经不相关了(我老了) - AndersK
显示剩余2条评论

0


我之前也遇到过同样的问题,我是这样解决的

while (fgets(line, sizeof(line), tsin) != 0) { //get an int value
   ... //doing stuff with line
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接