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

C语言:使用fgets/fputs逐行复制文件(MAXLINE=4)的缓冲区溢出求助

关于用fgets/fputs逐行复制文件及缓冲区溢出的问题解答

嘿,刚学C语言遇到这种卡壳的情况太正常了,别着急,咱们一步步把问题拆解开~

先纠正你对MAXLINE=4的误解

你以为缓冲区设为4会只返回每行前四个字符,这个理解有点偏差哦。fgets(buf, MAXLINE, fp)里的第二个参数是缓冲区的总字节数,它最多会读取MAXLINE-1个有效字符(因为要留1个字节存字符串结束符\0)。而且fgets的停止规则是:读到换行符、或者达到MAXLINE-1个字符、或者读到文件末尾,三者满足其一就停止。

举个例子:如果源文件里有一行是Hello World!,MAXLINE=4的话,fgets会分多次读取:第一次读Hel+\0,第二次读lo +\0,第三次读Wor+\0,直到把整行内容读完,剩下的字符会留在输入流里,下次调用fgets会接着读。

正确的逐行复制程序(MAXLINE=4)

先给你一个能正常工作的示例代码,你可以对比自己的代码找问题:

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

#define MAXLINE 4  // 缓冲区总大小为4,最多存3个有效字符+1个'\0'

int main() {
    FILE *src_file, *dest_file;
    char buf[MAXLINE];

    // 打开源文件和目标文件(记得替换成你自己的文件名)
    src_file = fopen("source.txt", "r");
    dest_file = fopen("destination.txt", "w");

    // 检查文件是否成功打开
    if (src_file == NULL || dest_file == NULL) {
        perror("Failed to open file");
        exit(EXIT_FAILURE);
    }

    // 逐段读取并写入,直到文件末尾
    while (fgets(buf, MAXLINE, src_file) != NULL) {
        fputs(buf, dest_file);
    }

    // 别忘了关闭文件
    fclose(src_file);
    fclose(dest_file);

    return 0;
}

运行这个程序后,目标文件会和源文件内容完全一致——哪怕源文件里有超长的行,fgets会自动分段读取,fputs会把这些分段依次写入,最终拼接成完整内容。

如何触发缓冲区溢出?

这里要明确:fgets本身是安全的,它严格限制了读取的字符数,不会让缓冲区溢出。要触发溢出,得用不安全的操作绕开这个限制,比如:

  1. 使用无长度限制的字符串拷贝函数
#include <stdio.h>
#include <string.h>

#define MAXLINE 4

int main() {
    char buf[MAXLINE];
    // 故意把长度为10的字符串复制到只有4字节的buf里
    strcpy(buf, "HelloWorld");
    printf("%s\n", buf);
    return 0;
}

"HelloWorld"加\0一共11个字节,远大于buf的4字节空间,超出的部分会覆盖栈上的其他数据,导致程序崩溃或者出现奇怪的行为。

  1. 手动越界写入缓冲区
#include <stdio.h>

#define MAXLINE 4

int main() {
    char buf[MAXLINE];
    // 手动给buf的第5个位置赋值(buf下标从0开始,合法下标是0-3)
    buf[4] = 'X';
    return 0;
}

这种直接越界访问数组的操作,也会造成缓冲区溢出,破坏内存中的其他数据。

最后再划个重点

  • fgets(buf, n, fp)的核心是最多读n-1个字符,不是只取每行前n-1个,超长行会被分段读取;
  • 用fgets+fputs复制文件时,无论缓冲区多大,都能完整复制内容;
  • 要触发缓冲区溢出,得用不安全的字符串操作或者手动越界,fgets本身不会导致溢出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 09:34:14