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

C语言中用getline读取输入到二维数组并空行终止的可行性咨询

当然可以在C语言里用getline()实现这个需求!其实getline()本身就是POSIX标准里的C函数(并不是C++专属哦),咱们可以结合动态内存分配来构建二维数组,一步步拆解怎么做:

核心思路

我们可以用指针数组(char** lines)来模拟二维数组:每个元素指向getline()为每行输入分配的字符串。同时需要记录当前存储的行数和数组的初始容量(避免频繁扩容影响效率),直到读到空行时停止。

完整代码示例

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

int main() {
    char** lines = NULL;       // 存储所有行的指针数组
    size_t line_count = 0;     // 当前已存储的行数
    size_t capacity = 4;       // 指针数组的初始容量
    char* current_line = NULL; // 存储当前行的临时指针
    size_t current_cap = 0;    // 当前行的内存容量

    // 初始化指针数组
    lines = malloc(capacity * sizeof(char*));
    if (lines == NULL) {
        perror("malloc failed");
        return EXIT_FAILURE;
    }

    printf("请输入内容,空行结束:\n");
    while (1) {
        // 读取一行输入
        ssize_t read_len = getline(&current_line, &current_cap, stdin);
        if (read_len == -1) {
            // 读取错误或到达EOF,直接退出循环
            break;
        }

        // 判断空行:读取的内容只有换行符
        if (read_len == 1 && current_line[0] == '\n') {
            break;
        }

        // 可选:去掉末尾的换行符(如果不需要保留换行的话)
        if (current_line[read_len - 1] == '\n') {
            current_line[read_len - 1] = '\0';
        }

        // 检查指针数组是否需要扩容
        if (line_count >= capacity) {
            capacity *= 2; // 通常扩容为原来的2倍,平衡效率和内存占用
            char** temp = realloc(lines, capacity * sizeof(char*));
            if (temp == NULL) {
                perror("realloc failed");
                // 内存分配失败时,要释放已分配的所有内存避免泄漏
                for (size_t i = 0; i < line_count; i++) {
                    free(lines[i]);
                }
                free(lines);
                free(current_line);
                return EXIT_FAILURE;
            }
            lines = temp;
        }

        // 为当前行单独分配内存并复制内容
        // 注意:不能直接存current_line的地址,因为getline会复用它的内存
        lines[line_count] = malloc(strlen(current_line) + 1);
        if (lines[line_count] == NULL) {
            perror("malloc for line failed");
            // 同样要清理已分配的内存
            for (size_t i = 0; i < line_count; i++) {
                free(lines[i]);
            }
            free(lines);
            free(current_line);
            return EXIT_FAILURE;
        }
        strcpy(lines[line_count], current_line);
        line_count++;
    }

    // 输出读取到的内容验证结果
    printf("\n你输入的内容是:\n");
    for (size_t i = 0; i < line_count; i++) {
        printf("第%d行:%s\n", (int)i+1, lines[i]);
    }

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

    return EXIT_SUCCESS;
}

关键细节说明

  • 为什么要复制current_line?:getline()会复用current_line的内存空间(如果当前容量足够),如果直接把current_line的地址存到指针数组里,后续读取的行会覆盖之前的内容,所以必须为每行单独分配内存并复制内容。
  • 空行判断:用read_len == 1 && current_line[0] == '\n'比strlen(current_line) == 1更高效,因为getline()返回的read_len已经包含了换行符的长度,不需要再调用strlen()遍历字符串。
  • 内存管理:一定要记得释放所有动态分配的内存,包括指针数组本身、每行的内存,以及getline()分配的current_line,避免内存泄漏。

补充说明

如果你的编译器不支持POSIX标准的getline()(比如部分老版本Windows编译器),可以用fgets()替代,核心逻辑不变,只是需要自己处理缓冲区和换行符的细节。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:25:51