动态二维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
相关产品推荐
相关产品推荐

