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

C语言读取文件每行存入char*数组的代码问题排查

问题原因

1. test[0]最终输出linha10的问题

  • 你定义的singleLine是栈上的一块固定内存地址,每次调用fgets都会覆盖这块内存的内容
  • 代码里test[0] = singleLine只是把test[0]的指针指向了singleLine的内存地址,并没有存储字符串的副本,循环执行到最后时singleLine里存储的是最后一行内容linha10,因此最终访问test[0]得到的是最后一行的值
  • 额外补充:while (!feof(in_file))的写法是错误的,feof标记是在读取操作失败(读到文件末尾之后再读一次)才会被置为真,你的写法会导致最后一行被重复读取一次

2. 无法得到实际元素个数的问题

  • sizeof是编译期运算符,计算的是数组占用的总字节数,char* test[30]的总大小就是30个指针的长度,和你实际往里面存了多少元素完全无关,因此不可能通过sizeof得到实际存储的元素数

解决方案

  1. 每次读取一行后,单独为字符串分配堆内存,拷贝字符串内容后再把指针存入数组,避免所有指针都指向同一块栈内存
  2. 额外定义一个计数变量,每成功存入一个元素就将计数+1,用这个变量记录实际存储的元素个数
  3. 修正文件读取的循环逻辑,用fgets的返回值作为循环判断条件

修正后示例代码

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

int main(){
    FILE *in_file  = fopen("arq.txt", "r"); 
    char singleLine[150];
    char* test[30];
    int actual_len = 0; // 记录实际存储的元素个数

    if (!in_file) 
    {   
        printf("Error! Could not open file\n"); 
        return 0;
    }

    // 修正循环判断条件,fgets返回NULL代表读取结束,同时限制不超出数组最大长度
    while (fgets(singleLine, 150, in_file) != NULL && actual_len < 30) {
        // 去掉fgets读取到的末尾换行符(可选,根据需求决定是否保留)
        singleLine[strcspn(singleLine, "\n")] = '\0';
        // 为字符串分配内存并拷贝内容
        test[actual_len] = strdup(singleLine);
        // 若编译环境不支持strdup,替换为下面两行即可:
        // test[actual_len] = malloc(strlen(singleLine) + 1);
        // strcpy(test[actual_len], singleLine);
        actual_len++;
    }

    printf("数组总长度: 30\n");
    printf("实际存储元素个数: %d\n", actual_len);
    // 遍历输出所有元素
    for (int i = 0; i < actual_len; i++) {
        printf("test[%d] = %s\n", i, test[i]);
    }

    // 用完释放堆内存,避免内存泄漏
    for (int i = 0; i < actual_len; i++) {
        free(test[i]);
    }

    fclose(in_file);
    return 0;
}

内容的提问来源于stack exchange,提问作者Nilton Schumacher F

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 02:45:01