如何在无限while循环中使用malloc动态存储用户输入内容?
动态扩容数组处理未知数量的输入行
嘿,这个场景太常见了!当没法提前知道要存储多少条输入时,我们可以用动态扩容的思路来解决——简单说就是先给数组分配一块初始内存,当快存满时就重新分配更大的空间,把旧数据拷贝过去,继续接收输入。下面一步步给你拆解解决方案:
核心思路
- 初始化一个小容量的数组(比如初始能存4条数据),同时记录当前已存储的元素数和数组总容量。
- 每次接收输入前,检查当前元素数是否等于数组容量:如果是,就用
realloc把数组扩容(通常扩为原来的2倍,这种指数扩容能减少内存分配的次数,效率更高)。 - 用
fgets读取输入行(别用feof当循环条件,它的触发时机容易踩坑),成功读取后就把内容存到数组里。 - 最后记得释放所有分配的内存,避免泄漏。
完整代码示例
#include <stdio.h> #include <stdlib.h> #include <string.h> #define INITIAL_CAPACITY 4 // 初始数组容量 #define MAX_LINE_LENGTH 167 // 每行最大长度 int main() { char **array = NULL; size_t capacity = INITIAL_CAPACITY; size_t count = 0; char buffer[MAX_LINE_LENGTH]; // 初始化数组 array = malloc(capacity * sizeof(char*)); if (array == NULL) { perror("malloc failed"); return 1; } // 读取输入行,直到EOF(Ctrl+D) while (fgets(buffer, MAX_LINE_LENGTH, stdin) != NULL) { // 检查是否需要扩容 if (count >= capacity) { // 扩容为原来的2倍 size_t new_capacity = capacity * 2; char **temp_array = realloc(array, new_capacity * sizeof(char*)); if (temp_array == NULL) { perror("realloc failed"); // 释放已分配的内存,避免泄漏 for (size_t i = 0; i < count; i++) { free(array[i]); } free(array); return 1; } array = temp_array; capacity = new_capacity; printf("数组已扩容,当前容量:%zu\n", capacity); // 可选的调试信息 } // 去掉换行符(如果需要的话) buffer[strcspn(buffer, "\n")] = '\0'; // 为当前行分配内存并拷贝内容 array[count] = malloc(strlen(buffer) + 1); // +1 存终止符'\0' if (array[count] == NULL) { perror("malloc for line failed"); // 清理已分配的内存 for (size_t i = 0; i < count; i++) { free(array[i]); } free(array); return 1; } strcpy(array[count], buffer); count++; } // 测试输出存储的内容 printf("\n你输入了%zu行内容:\n", count); for (size_t i = 0; i < count; i++) { printf("第%zu行:%s\n", i+1, array[i]); } // 释放所有内存 for (size_t i = 0; i < count; i++) { free(array[i]); } free(array); return 0; }
关键细节说明
- 不要用
feof作为循环条件:feof只有在尝试读取并到达EOF后才会返回真,直接用它会导致最后一行被重复处理,用fgets的返回值判断更准确。 realloc的安全用法:别直接把realloc的返回值赋值给原数组——如果分配失败,realloc会返回NULL,直接赋值会丢失原来的内存指针,导致内存泄漏。所以先存到临时变量,检查成功后再替换原数组。- 内存清理:任何内存分配失败的情况下,都要把之前已经分配的内存全部释放,避免泄漏。
- 换行符处理:
fgets会把输入的换行符\n也读进缓冲区,用strcspn可以方便地把它替换成字符串终止符\0。
内容的提问来源于stack exchange,提问作者Samun
相关产品推荐
相关产品推荐

