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

C语言数组无法保留值:读取文本文件时元素被覆盖问题

问题分析与修复:数组元素被覆盖的原因及解决办法

核心问题

你的代码里char* posList[50];是一个指针数组,每次循环执行posList[lineCnt] = line;时,只是把栈上固定数组line的地址赋值给了指针元素。而fgets每次都会把新读取的内容写入同一个line数组,所以所有posList里的指针最终都指向同一块内存空间——最后一次fgets写入的内容自然会覆盖之前的所有"假象"。

两种可行的修复方案

方案1:为每个指针分配独立内存

使用malloc为每个字符串分配单独的内存空间,再用strcpy把line里的内容复制过去:

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

#define MAX_LINE_LENGTH 16
#define MAX_LINES 50

int main()
{
    int lineCnt = 0;
    FILE *textfile;
    char line[MAX_LINE_LENGTH];
    char* posList[MAX_LINES];
    
    textfile = fopen("pos-list.txt", "r");
    if(textfile == NULL)
    {
        system("cls");
        fprintf(stderr, "**File open failed\n Make sure there is a pos-list.txt file");
        return 1;
    }
    
    system("cls");
    
    while(fgets(line, MAX_LINE_LENGTH, textfile) && lineCnt < MAX_LINES)
    {
        // 去掉换行符(可选,根据需求调整)
        line[strcspn(line, "\n")] = '\0';
        
        // 分配内存并复制内容
        posList[lineCnt] = malloc(strlen(line) + 1);
        if(posList[lineCnt] == NULL)
        {
            fprintf(stderr, "Memory allocation failed");
            // 释放已分配的内存再退出
            for(int i=0; i<lineCnt; i++) free(posList[i]);
            fclose(textfile);
            return 1;
        }
        strcpy(posList[lineCnt], line);
        
        printf("Line %d: %s\n", lineCnt, line);
        printf("posList[%d] = %s\n", lineCnt, posList[lineCnt]);
        printf("posList[0] = %s\n", posList[0]);
        
        lineCnt++;
    }
    
    // 使用完后释放内存,避免泄漏
    for(int i=0; i<lineCnt; i++)
    {
        free(posList[i]);
    }
    fclose(textfile);
    return 0;
}

方案2:使用二维数组直接存储字符串

如果预先知道最大行数和每行长度,可以直接定义二维数组,避免动态内存分配:

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

#define MAX_LINE_LENGTH 16
#define MAX_LINES 50

int main()
{
    int lineCnt = 0;
    FILE *textfile;
    char posList[MAX_LINES][MAX_LINE_LENGTH]; // 二维数组,每个元素是独立的字符串
    
    textfile = fopen("pos-list.txt", "r");
    if(textfile == NULL)
    {
        system("cls");
        fprintf(stderr, "**File open failed\n Make sure there is a pos-list.txt file");
        return 1;
    }
    
    system("cls");
    
    while(fgets(posList[lineCnt], MAX_LINE_LENGTH, textfile) && lineCnt < MAX_LINES)
    {
        // 去掉换行符(可选)
        posList[lineCnt][strcspn(posList[lineCnt], "\n")] = '\0';
        
        printf("Line %d: %s\n", lineCnt, posList[lineCnt]);
        printf("posList[%d] = %s\n", lineCnt, posList[lineCnt]);
        printf("posList[0] = %s\n", posList[0]);
        
        lineCnt++;
    }
    
    fclose(textfile);
    return 0;
}

额外优化点

  • 移除了无用的lineCntPOSlist和i变量,简化代码结构
  • 增加lineCnt < MAX_LINES判断,防止数组越界
  • 加入换行符去除逻辑(strcspn),避免字符串携带多余换行符
  • 方案1补充了内存分配失败的异常处理,以及使用后的内存释放逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 11:31:02