C语言不使用<string.h>库分割单行输入并通过malloc为各元素分配内存的方法
不依赖<string.h>实现单行输入分割与元素动态内存分配
以下实现默认以空格为分隔符,支持跳过连续空格,所有字符串操作手动实现,完全不依赖<string.h>库,每个分割后的元素都会单独调用malloc分配刚好适配内容大小的内存空间。
核心实现步骤
- 读取完整单行输入内容
- 遍历输入统计分割后的元素总数,分配对应大小的指针数组存储各元素地址
- 二次遍历输入逐个提取元素,计算单个元素长度后分配内存、手动拷贝内容
完整可运行代码
#include <stdio.h> #include <stdlib.h> // 自定义分隔符判断规则,可按需修改为逗号、制表符等其他分隔符 #define is_separator(c) (c == ' ' || c == '\n' || c == '\r') int main() { char *input = NULL; size_t input_buf_len = 0; ssize_t read_len; // 读取单行输入,自动分配输入缓冲区 read_len = getline(&input, &input_buf_len, stdin); if (read_len == -1) { perror("读取输入失败"); return 1; } // 统计分割后的元素总数 int elem_count = 0; int in_element_flag = 0; for (int i = 0; input[i] != '\0'; i++) { if (!is_separator(input[i]) && !in_element_flag) { elem_count++; in_element_flag = 1; } else if (is_separator(input[i])) { in_element_flag = 0; } } // 分配存储元素指针的数组,末尾预留NULL作为遍历哨兵 char **elements = malloc((elem_count + 1) * sizeof(char*)); if (elements == NULL) { perror("指针数组内存分配失败"); free(input); return 1; } elements[elem_count] = NULL; // 逐个提取元素并分配内存 int current_elem_idx = 0; int elem_start_pos = 0; in_element_flag = 0; for (int i = 0; input[i] != '\0'; i++) { if (!is_separator(input[i]) && !in_element_flag) { elem_start_pos = i; in_element_flag = 1; } else if (is_separator(input[i]) && in_element_flag) { int elem_len = i - elem_start_pos; // 分配内存时额外多1位存储字符串结束符'\0' elements[current_elem_idx] = malloc((elem_len + 1) * sizeof(char)); if (elements[current_elem_idx] == NULL) { perror("元素内存分配失败"); // 释放已分配内存避免泄漏 for (int j = 0; j < current_elem_idx; j++) { free(elements[j]); } free(elements); free(input); return 1; } // 手动拷贝元素内容,无需调用strcpy for (int j = 0; j < elem_len; j++) { elements[current_elem_idx][j] = input[elem_start_pos + j]; } elements[current_elem_idx][elem_len] = '\0'; current_elem_idx++; in_element_flag = 0; } } // 测试:输出分割结果 printf("共分割得到%d个元素:\n", elem_count); for (int i = 0; elements[i] != NULL; i++) { printf("第%d个元素:%s\n", i+1, elements[i]); } // 使用完成后释放所有堆内存 for (int i = 0; elements[i] != NULL; i++) { free(elements[i]); } free(elements); free(input); return 0; }
注意事项
- 如果运行环境不支持POSIX标准的
getline函数,可以替换为fgets读取到固定大小的缓冲区后再做处理 - 修改
is_separator宏的判断逻辑即可适配不同的分隔符需求,比如要按逗号分割改为(c == ',' || c == '\n' || c == '\r')即可 - 代码已经包含完整的异常分支内存释放逻辑,避免内存泄漏,实际业务使用时可直接复用该释放逻辑
内容的提问来源于stack exchange,提问作者joig
相关产品推荐
相关产品推荐

