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

C语言初学者求助:无法将文件内容正确存入数组

问题描述

实现读取文件内容填充到数组时出现异常:执行get_dico函数后,数组所有元素均显示最后一个字符"s",而非预期的{a,b,c,s}。

结构体定义

typedef struct  {
    void* * data  ;         
    size_t max_size;       
    size_t actual_size;    

    void* (*delete_data)(void*); 
    int (*equal_data)(void*,void*); 
    void (*fprint_data)(void*, FILE*); 
} * table_t;

功能实现代码

void get_dico(table_t tab , const char * dico ) {
    FILE *fp = NULL ;
    int i = 0 ;
    if((fp = fopen(dico,"r")) != NULL){
        char word[256];
        while(fscanf(fp,"%s",word) == true ){          
            tab->data[i] = word ;
            i ++ ;
        }
        fclose(fp);
    }
}

字典文件内容

a
b
c
s

问题分析

核心问题是所有数组元素都指向了同一个局部内存地址:
word是函数内的局部数组,循环中每次读取新字符串都会覆盖它的内容,但你只是把word的地址赋值给tab->data[i]。最终所有元素都指向这块固定的局部内存,自然显示的都是最后一次写入的"s"。

修复方案

每次读取字符串后,为每个字符串分配独立的内存空间,复制内容后再存入数组。可以用strdup(需引入<string.h>)或手动malloc+strcpy实现,同时记得更新结构体的actual_size字段。

修复后的代码:

#include <string.h>

void get_dico(table_t tab , const char * dico ) {
    FILE *fp = NULL ;
    int i = 0 ;
    if((fp = fopen(dico,"r")) != NULL){
        char word[256];
        // fscanf成功读取一个字符串时返回1,用1代替true更严谨
        while(fscanf(fp,"%s",word) == 1 ){          
            // 分配内存并复制字符串
            tab->data[i] = strdup(word);
            // 若无法使用strdup,可手动实现:
            // tab->data[i] = malloc(strlen(word) + 1);
            // if(tab->data[i] != NULL) strcpy(tab->data[i], word);
            
            i ++ ;
            // 更新结构体实际元素数量
            if(i <= tab->max_size){
                tab->actual_size = i;
            }
        }
        fclose(fp);
    }
}
额外注意事项
  1. 确保tab->data已提前分配足够内存(max_size需大于等于文件中单词总数),避免数组越界。
  2. 后续需通过结构体的delete_data函数或直接free释放每个字符串的内存,防止内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 04:32:08