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

行数、每行单词数未知的文件输入如何动态分配3D char数组

动态存储多行多单词输入的实现方案

以下提供两种可直接落地的实现,完全兼容你期望的arr[行下标][单词下标]访问形式。


方案1:贴合原三维数组思路的动态分配实现

核心逻辑

你最初的三维数组思路完全可行,只需要把静态分配改成堆上的动态逐级分配即可,需要额外配套两个变量记录行数、每行的单词数,避免越界访问:

  • 用三级指针char*** arr对应三维字符数组
  • 用int row_cnt记录总行数
  • 用int* word_cnt_per_row记录每行的单词数量

核心代码示例

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

#define MAX_WORD_LEN 30 // 单词最大长度,和你预设的一致

int main() {
    char*** arr = NULL;
    int* word_cnt_per_row = NULL;
    int row_cnt = 0;
    char line_buf[1024]; // 单行最大长度,可按需调整

    FILE* fp = fopen("input.txt", "r");
    if (!fp) {
        perror("文件打开失败");
        return 1;
    }

    // 逐行读取文件
    while (fgets(line_buf, sizeof(line_buf), fp)) {
        // 扩容行维度的数组
        arr = realloc(arr, (row_cnt + 1) * sizeof(char**));
        word_cnt_per_row = realloc(word_cnt_per_row, (row_cnt + 1) * sizeof(int));

        // 统计当前行的单词数
        int word_cnt = 0;
        char* tmp = strdup(line_buf);
        char* p = strtok(tmp, " \t\n\r");
        while (p) {
            word_cnt++;
            p = strtok(NULL, " \t\n\r");
        }
        free(tmp);
        word_cnt_per_row[row_cnt] = word_cnt;

        // 分配当前行的单词指针数组
        arr[row_cnt] = malloc(word_cnt * sizeof(char*));
        // 逐个分配单词空间并写入内容
        p = strtok(line_buf, " \t\n\r");
        for (int i = 0; i < word_cnt; i++) {
            arr[row_cnt][i] = malloc(MAX_WORD_LEN * sizeof(char));
            strncpy(arr[row_cnt][i], p, MAX_WORD_LEN - 1);
            arr[row_cnt][i][MAX_WORD_LEN - 1] = '\0'; // 强制字符串结束,避免溢出
            p = strtok(NULL, " \t\n\r");
        }
        row_cnt++;
    }
    fclose(fp);

    // 访问示例:和你预想的静态数组用法完全一致
    // printf("%s", arr[1][2]); 直接取第2行第3个单词

    // 内存释放逻辑,避免泄漏
    for (int i = 0; i < row_cnt; i++) {
        for (int j = 0; j < word_cnt_per_row[i]; j++) {
            free(arr[i][j]);
        }
        free(arr[i]);
    }
    free(arr);
    free(word_cnt_per_row);

    return 0;
}

方案2:优化内存效率的改进方案

优化点

因为你预设了单词最大长度固定为30,可以把每行所有单词的存储空间合并为一块连续内存,减少malloc次数、降低内存碎片,访问速度也更快:
仅需要修改分配和释放的部分逻辑:

// 分配单词部分替换为:
arr[row_cnt] = malloc(word_cnt * sizeof(char*));
char* whole_line_buf = malloc(word_cnt * MAX_WORD_LEN * sizeof(char)); // 一次性分配整行单词空间
p = strtok(line_buf, " \t\n\r");
for (int i = 0; i < word_cnt; i++) {
    arr[row_cnt][i] = whole_line_buf + i * MAX_WORD_LEN; // 每个单词指针指向对应偏移位置
    strncpy(arr[row_cnt][i], p, MAX_WORD_LEN - 1);
    arr[row_cnt][i][MAX_WORD_LEN - 1] = '\0';
    p = strtok(NULL, " \t\n\r");
}

// 释放部分替换为:
for (int i = 0; i < row_cnt; i++) {
    free(arr[i][0]); // 释放整行的连续单词缓冲区
    free(arr[i]);
}
free(arr);
free(word_cnt_per_row);

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

相关产品推荐
方舟 Agent Plan

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

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