如何在C语言中动态添加用户输入字符串至数组并实现数组扩容?
动态扩展的字符串数组实现方案
首先,咱们先拆解下你代码里的几个关键问题,再一步步完善成符合需求的程序:
你的代码里的核心问题
char* strings[10];是栈上的固定大小指针数组,不能用malloc直接赋值给它——栈数组的地址是固定的,没法重新分配。要实现动态扩容,得用堆上分配的二级指针(char**)来作为数组的容器。char *input_str;是个野指针,没有分配内存空间就直接用fgets写入,会导致程序崩溃。- 缺少循环逻辑,也没有处理数组满了之后的扩容逻辑,更没做输入的存储和管理。
完整实现代码
下面是符合你需求的完整代码,我会在代码里加注释说明关键部分:
#include <stdio.h> #include <stdlib.h> #include <string.h> #define INITIAL_CAPACITY 10 // 初始数组容量 #define RESIZE_FACTOR 2 // 扩容倍数 int main() { // 1. 初始化动态字符串数组:存储字符串指针的数组,初始容量10 char** strings = malloc(INITIAL_CAPACITY * sizeof(char*)); if (strings == NULL) { perror("Failed to allocate memory for strings array"); return 1; } int current_count = 0; // 当前已存储的字符串数量 int current_capacity = INITIAL_CAPACITY; // 当前数组的最大容量 char input_buf[1024]; // 用固定大小的缓冲区接收输入,避免每次分配内存 printf("Enter strings (type 'quit' to exit):\n"); // 2. 循环接收用户输入 while (1) { printf("> "); // 读取输入到缓冲区,处理可能的换行符 if (fgets(input_buf, sizeof(input_buf), stdin) == NULL) { break; // 读取失败或EOF时退出循环 } // 去掉fgets读取到的末尾换行符 input_buf[strcspn(input_buf, "\n")] = '\0'; // 退出条件:用户输入quit if (strcmp(input_buf, "quit") == 0) { break; } // 3. 检查数组是否已满,需要扩容 if (current_count >= current_capacity) { int new_capacity = current_capacity * RESIZE_FACTOR; char** temp = realloc(strings, new_capacity * sizeof(char*)); if (temp == NULL) { perror("Failed to resize strings array"); // 扩容失败时,先释放已分配的内存避免泄漏 for (int i = 0; i < current_count; i++) { free(strings[i]); } free(strings); return 1; } strings = temp; current_capacity = new_capacity; printf("Array resized to %d slots\n", new_capacity); } // 4. 为输入的字符串分配内存并复制到数组中 strings[current_count] = malloc(strlen(input_buf) + 1); // +1存终止符 if (strings[current_count] == NULL) { perror("Failed to allocate memory for input string"); // 清理已分配的内存 for (int i = 0; i < current_count; i++) { free(strings[i]); } free(strings); return 1; } strcpy(strings[current_count], input_buf); current_count++; printf("Added string %d: '%s'\n", current_count, strings[current_count-1]); } // 5. 程序结束前释放所有分配的内存,避免内存泄漏 printf("\nCleaning up %d strings...\n", current_count); for (int i = 0; i < current_count; i++) { free(strings[i]); } free(strings); return 0; }
关键逻辑解释
- 动态数组初始化:用
malloc分配初始10个字符串指针的空间,而不是栈数组,这样后续可以用realloc扩容。 - 输入处理:用固定大小的缓冲区
input_buf接收输入,比每次动态分配更高效,然后再为每个输入的字符串单独分配内存存储,确保每个字符串有独立的空间。 - 扩容逻辑:当已存储的字符串数量等于当前容量时,用
realloc把数组大小乘2,扩容后更新容量值。 - 内存管理:每次分配内存都做
NULL检查,避免内存分配失败导致的崩溃;程序结束前要逐个释放每个字符串的内存,再释放数组本身的内存,防止内存泄漏。 - 退出机制:添加了输入
quit退出循环的逻辑,方便测试。
这样运行程序后,你就可以不断输入字符串,数组会在满了之后自动扩容,完全符合你的需求。
内容的提问来源于stack exchange,提问作者quiccode
相关产品推荐
相关产品推荐

