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

C语言读取多文本文件填充动态二维数组问题求解

问题核心原因

C语言为值传递,你当前readWords函数中对形参char ** arr的赋值仅会修改函数栈上的临时副本,不会对main函数中传入的arr_words生效,因此外层无法拿到分配好的数组地址。

具体修改点

  • 将readWords的第二个参数修改为三级指针char *** arr,用于接收外层char **类型变量的地址,实现对外部变量的修改
  • 函数内操作数组时先对三级指针解引用拿到char **类型的数组地址
  • 优化内存操作:getWord已经通过strdup分配了单词对应的内存,无需额外分配100字节再拷贝,避免内存泄漏
  • 修正普通文件判断逻辑,使用标准宏DT_REG替代硬编码数值4,兼容性更好
  • 增加文件打开失败、入参为空的边界判断,提升代码健壮性

修改后的完整代码

#include <string.h>
#include <malloc.h>
#include <stdio.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <ctype.h>

char *getWord(FILE *fp){
    char word[100];
    int ch, i=0;

    while(EOF!=(ch=fgetc(fp)) && !isalpha(ch))
        ;//跳过非字母字符
    if(ch == EOF)
        return NULL;
    do{
        word[i++] = tolower(ch);
    }while(EOF!=(ch=fgetc(fp)) && isalpha(ch));

    word[i]='\0';
    return strdup(word);
}

// 二级指针改为三级指针
int readWords(const char * fn,char *** arr){
    char *word;
    FILE * fp;
    int size=0;
    //首次读取统计单词总数
    fp=fopen(fn,"r");
    if(!fp) return 0; // 增加文件打开失败判断

    while((word=getWord(fp)) != NULL){
        size++;
        free(word); // 统计阶段不需要保留单词,释放strdup分配的内存
    }

    fclose(fp);
    printf("size:%d\n",size);
    // 对三级指针解引用后赋值,修改外层的数组指针
    *arr = (char **) malloc (size * sizeof (char *));
    // 重新读取文件填充动态数组
    fp=fopen(fn,"r");
    for (int i = 0; i < size; i++){
        // 直接赋值getWord返回的内存,无需额外分配
        (*arr)[i] = getWord(fp);
    }
    fclose(fp);

    return size;
}

int main(int narg, char *arg[] )
{
    if(narg < 2){
        printf("请传入目录路径作为参数\n");
        return 1;
    }
    struct dirent *de;  //目录项指针
    char absdir[256];
    char absfn[256];
    int s;

    //opendir返回DIR类型指针
    DIR *dr = opendir(arg[1]);
    strcpy(absdir,arg[1]);
    strcat(absdir,"/");

    if (dr == NULL)  //无法打开目录时返回NULL
    {
        printf("无法打开指定目录" );
        return 0;
    }

    while ((de = readdir(dr)) != NULL){
        // 用标准宏判断是否为普通文件,避免硬编码兼容性问题
        if (de->d_type == DT_REG){ 
            strcpy(absfn,absdir);
            strcat(absfn,de->d_name);
            printf("abs_fn:%s \n",absfn);
            char** arr_words;

            s=readWords(absfn,&arr_words);

            printf("%s 单词总数:%d\n", absfn,s);
            for (int i=0;i<s;i++)
                printf("第%d个单词:%s\n",i,arr_words[i]);
            
            //释放二维数组内存
            for(int i=0;i<s;i++)
                free(arr_words[i]);
            free(arr_words);

        }
            
    }
    closedir(dr);    
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 06:06:03