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

如何在无限while循环中使用malloc动态存储用户输入内容?

动态扩容数组处理未知数量的输入行

嘿,这个场景太常见了!当没法提前知道要存储多少条输入时,我们可以用动态扩容的思路来解决——简单说就是先给数组分配一块初始内存,当快存满时就重新分配更大的空间,把旧数据拷贝过去,继续接收输入。下面一步步给你拆解解决方案:

核心思路

  1. 初始化一个小容量的数组(比如初始能存4条数据),同时记录当前已存储的元素数和数组总容量。
  2. 每次接收输入前,检查当前元素数是否等于数组容量:如果是,就用realloc把数组扩容(通常扩为原来的2倍,这种指数扩容能减少内存分配的次数,效率更高)。
  3. 用fgets读取输入行(别用feof当循环条件,它的触发时机容易踩坑),成功读取后就把内容存到数组里。
  4. 最后记得释放所有分配的内存,避免泄漏。

完整代码示例

#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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:04:27