You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用fgets()读取文件:循环读取与单次读取的差异疑问

单次调用fgets()和循环读取文件的区别

fgets()的工作逻辑是:一次最多读取缓冲区大小-1个字符,碰到换行符或者文件结尾就停止读取。你现在的代码能正常运行,完全是因为你的test.txt内容很短,刚好能被一次读取覆盖,但单次调用和循环调用的核心区别体现在这几个方面:

适用场景天差地别

  • 单次调用:只适合你完全确定文件内容的长度不超过缓冲区大小,且只有一行的情况。比如你的例子里"Hello world!"长度远小于你定义的string[30],所以一次就读完了。
  • 循环调用:是通用的文件读取方式,不管文件有几百行、内容有多长,都能逐段把整个文件的内容读完,不会遗漏。

读取结果的完整性不同

  • 单次调用:如果文件内容长度超过缓冲区的可用空间(比如你的string能存29个有效字符),只会读取前29个字符,剩下的内容会留在文件指针里,不会被处理;如果文件有多行,也只能读到第一行。
  • 循环调用:会反复调用fgets(),直到它返回NULL(代表读到文件结尾或者读取出错),能保证把整个文件的内容都处理完毕。

举个实际的例子,如果你的test.txt内容是:

Hello world!
This is a line that's longer than 29 characters, let's see what happens now.

用你的代码单次调用fgets(),只会输出第一行;如果第一行本身就超过29字符,比如"abcdefghijklmnopqrstuvwxyz12345"(超过29个字符),那fgets()只会读取前29个字符,剩下的内容就丢了。但用循环读取的话,就能把两行内容都完整读出来。

你的示例代码:

#include <stdio.h>
#include <stdlib.h>

int main() {
    FILE *file = NULL;
    char string[30];
    file = fopen("test.txt", "r"); //test.txt contains "Hello world!"

    if (file == NULL) {
        puts("ERROR");
        return 1;
    }

    fgets(string, 30, file);

    puts(string);

    fclose(file);

    return 0;

}

输出结果:

Hello world!

内容的提问来源于stack exchange,提问作者tomasvie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 17:15:15