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

C语言读取文本文件行到char**指针时,所有索引均指向最后行的问题

解决读取文件行到字符串数组时所有元素指向同一行的问题

嘿,我来帮你搞定这个问题!你现在踩了一个C语言里非常典型的新手坑,咱们一步步拆解原因和解决方案:

问题根源

你代码里的char line[MAX_LINE];是一个栈上的固定大小数组,每次调用fgets都会把读取到的行内容写到这个数组里,直接覆盖掉之前的内容。而lines[count] = line;这行代码,只是把这个数组的内存地址赋值给了lines的每个元素,并没有把字符串的实际内容复制过去。

打个比方:你有一个盒子(line数组),每次装新东西(新行)就把旧的换掉,然后给1000个标签(lines[0]到lines[999])都贴在同一个盒子上,最后打开任何一个标签指向的盒子,看到的自然都是最后装进去的东西。

另外,你给lines分配内存的方式也不对:malloc(10000*200*sizeof(char))是分配了一大块字符空间,但char** lines需要的是字符指针数组,应该分配的是指针的空间,不是字符的空间。

修正后的代码

下面是修改好的代码,我加了详细注释:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LINE 10000

int main() {
    FILE *fp = NULL;
    char line[MAX_LINE];
    // 先分配2000个字符指针的空间(对应你后面循环的2000行上限)
    char** lines = (char**)malloc(2000 * sizeof(char*));
    if (lines == NULL) { // 检查内存分配是否成功
        perror("malloc failed");
        return 1;
    }
    int count = 0;
    fp = fopen("test.txt","r");
    if (fp == NULL) { // 检查文件是否成功打开
        perror("fopen failed");
        free(lines);
        return 1;
    }
    // 读取每行,为每行单独分配内存并复制内容
    while(fgets(line, MAX_LINE, fp) && count < 2000) { // 加count限制避免数组越界
        // 方法1:用strdup直接复制字符串(内部会自动分配内存)
        lines[count] = strdup(line);
        // 方法2:手动分配内存+复制(如果你的环境没有strdup的话)
        // lines[count] = malloc(strlen(line) + 1); // +1是为了存字符串结束符'\0'
        // if (lines[count] == NULL) {
        //     perror("malloc line failed");
        //     // 这里要记得释放已经分配的内存再退出
        //     for (int i=0; i<count; i++) free(lines[i]);
        //     free(lines);
        //     fclose(fp);
        //     return 1;
        // }
        // strcpy(lines[count], line);
        count++;
    }
    fclose(fp);
    // 打印所有行,用实际读取到的行数count,避免访问未初始化的指针
    for(int i =0; i<count;i++){
        printf("%s",lines[i]);
    }
    // 记得释放所有分配的内存,避免内存泄漏
    for (int i=0; i<count; i++) {
        free(lines[i]);
    }
    free(lines);
    return 0;
}

关键改动点

  • 修正lines的内存分配:现在分配的是2000个char*的空间,对应2000行的指针位置
  • 为每行单独分配内存并复制内容:用strdup或者malloc+strcpy,让每个lines[i]都指向独立的内存区域,不会被后续的fgets覆盖
  • 增加错误检查:对内存分配、文件打开做了异常处理,避免程序崩溃
  • 释放内存:最后手动释放所有分配的堆内存,防止内存泄漏
  • 打印逻辑优化:用实际读取到的行数count循环,避免访问未初始化的指针

这样修改后,每个lines[i]就会指向对应行的独立内容,不会再全部显示最后一行啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 19:42:52