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

动态二维char数组Realloc问题:读取stdin空格分隔字符串

嘿,我来帮你搞定这个动态二维字符数组的问题!咱们一步步拆解,帮你实现从标准输入读取未知数量的空格分隔字符串,动态扩容存储,最后拿到第一个字符串的首字符。

核心实现思路

要处理未知数量的字符串,我们需要两层动态分配:

  • 第一层是指针数组(也就是你说的二维char数组的外层):用来存储每个字符串的首地址,需要随着字符串数量增加用realloc扩容。
  • 第二层是每个字符串的内存:每个字符串长度也不确定,所以要为每个读取到的字符串单独动态分配内存。
完整代码示例

下面是可直接运行的代码,注释里写清了每一步的逻辑:

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

int main() {
    // 初始化指针数组:初始能存2个字符串,后续按需扩容
    size_t current_array_size = 2;
    char **str_array = malloc(current_array_size * sizeof(char *));
    if (!str_array) {
        perror("Failed to allocate initial array");
        exit(EXIT_FAILURE);
    }
    size_t string_count = 0; // 已存储的字符串数量

    char *input_line = NULL;
    size_t line_capacity = 0;
    ssize_t line_length;

    // 逐行读取标准输入(处理多行输入的情况)
    while ((line_length = getline(&input_line, &line_capacity, stdin)) != -1) {
        // 去掉行尾的换行符(如果存在)
        if (line_length > 0 && input_line[line_length - 1] == '\n') {
            input_line[line_length - 1] = '\0';
        }

        // 用strtok分割当前行的字符串,分隔符为空格
        char *token = strtok(input_line, " ");
        while (token != NULL) {
            // 检查指针数组是否已满,需要扩容
            if (string_count >= current_array_size) {
                // 翻倍扩容(优化性能,避免频繁realloc)
                current_array_size *= 2;
                char **temp_array = realloc(str_array, current_array_size * sizeof(char *));
                if (!temp_array) {
                    perror("Failed to reallocate array");
                    // 出错时先释放已分配的内存,避免泄漏
                    for (size_t i = 0; i < string_count; i++) {
                        free(str_array[i]);
                    }
                    free(str_array);
                    free(input_line);
                    exit(EXIT_FAILURE);
                }
                str_array = temp_array;
            }

            // 为当前字符串分配内存(长度+1是为了存字符串终止符'\0')
            str_array[string_count] = malloc(strlen(token) + 1);
            if (!str_array[string_count]) {
                perror("Failed to allocate memory for string");
                // 清理已分配的内存
                for (size_t i = 0; i < string_count; i++) {
                    free(str_array[i]);
                }
                free(str_array);
                free(input_line);
                exit(EXIT_FAILURE);
            }

            // 复制字符串到分配的内存中
            strcpy(str_array[string_count], token);
            string_count++;

            // 获取下一个空格分隔的字符串
            token = strtok(NULL, " ");
        }
    }

    // 释放getline分配的行内存
    free(input_line);

    // 按需求输出第一个字符串的首字符
    if (string_count > 0) {
        printf("%c\n", str_array[0][0]);
    } else {
        printf("No valid input strings found.\n");
    }

    // 最后释放所有动态分配的内存,避免泄漏
    for (size_t i = 0; i < string_count; i++) {
        free(str_array[i]);
    }
    free(str_array);

    return EXIT_SUCCESS;
}
关键细节说明
  • 扩容策略:采用翻倍扩容而不是每次加1,这样可以减少realloc的调用次数,降低内存移动的开销,让整体效率更优。
  • 内存安全:每次malloc和realloc后都检查返回值,确保内存分配成功;出错时会先释放已分配的所有内存,避免内存泄漏。
  • 输入处理:用getline读取整行输入,比fgets更安全(不需要预先知道行长度),再用strtok分割空格分隔的字符串,自动跳过连续空格,符合你的需求。
  • 测试示例:当输入hello world时,程序会输出h,完全符合你的预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 11:00:20