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

C语言实现字符串分割函数时char**缓冲区仅首元素可写入问题

C语言split函数仅返回第一个分割结果的问题修复

问题现象

实现按指定分隔符拆分字符串为字符串数组的函数时,char**类型的结果数组仅第一个索引可正常写入内容。例如将字符串"Hello;;world;;!"按分隔符";;"分割时,预期返回[ "Hello", "world", "!" ],实际仅得到[ "Hello" ]。

原始问题代码

split函数实现

#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include "strings.h"

int split(char **dest, const char *src, const char *splitStr) {
    char buffer[16384];
    int counter = 0;
    int len = strlen(splitStr);
    int flag = 0;
    int start = 0;
    for (int i = 0; i < strlen(src); i++) {
        flag = 0;
        if (src[i] == splitStr[0]) {
            for (int j = 1; j < len; j++) {
                //check if all elements in delimiter are in string
                if (src[i + j] == splitStr[j] && j != (len - 1)) {
                    continue;
                }
                else if(src[i + j] == splitStr[j] && j == (len - 1)) {
                    buffer[i] = '\0';
                    dest[counter] = malloc(sizeof(char) * (i - start + 1));
                    strncpy(dest[counter], buffer + start, (i - start));
                    start = i + (len-1)
                    flag = 1;
                    i += (len - 1);
                    counter++;
                }
                //if not break
                else {
                    break;
                }
            }
        }
    
        if (i == (strlen(src) - 1)) {
            buffer[i] = src[i];
            buffer[i + 1] = '\0';
            counter++;
            break;
        }
        if (flag == 0) {
            buffer[i] = src[i];
        }
    }
    return counter;
}

调用代码

auto src = "Hello;;world;;!";
auto buffer = (char **)malloc(32);
int count = split(buffer, src, ";;");

错误点汇总

  • 语法错误:匹配分隔符后的start = i + (len-1)语句末尾缺少分号,无法正常编译。
  • 结果缓冲区分配错误:malloc(32)仅分配了32字节连续内存,虽然64位系统下勉强能存4个char*指针,但没有按指针类型计算分配大小,一旦分割结果超过4个就会出现内存越界。
  • 缓冲区写入下标逻辑错误:复用原字符串下标i作为临时buffer的写入下标,匹配到第一个分隔符后i会跳过分隔符位置,后续写入buffer时会出现下标断层,buffer+start指向的内存空间没有有效内容,拷贝自然失败。
  • 字符串拷贝缺失终止符:使用strncpy拷贝固定长度内容时不会自动追加字符串结束符'\0',会导致字符串内存越界。
  • 最后一段内容未写入结果数组:循环走到原字符串末尾时,仅操作了临时buffer、累加了计数器,没有给最后一个分割结果分配内存、也没有执行拷贝操作,最后一段内容直接丢失。
  • 分隔符匹配逻辑缺陷:内层匹配循环从j=1开始,当分隔符长度为1时循环永远不会执行,无法匹配单字符分隔符;匹配成功后下一段起始位置计算为i + len -1,会把分隔符的最后一个字符算入下一段内容。
  • 循环效率问题:每次循环都调用strlen(src)计算字符串长度,时间复杂度从O(n)升到O(n²)。

修正后实现

修正后的split函数

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

int split(char **dest, const char *src, const char *splitStr) {
    int src_len = strlen(src);
    int split_len = strlen(splitStr);
    int counter = 0;
    int buf_pos = 0; // 单独维护临时缓冲区的写入下标,不复用原串下标
    char buffer[16384];

    // 处理分隔符为空的边界情况
    if (split_len == 0) {
        dest[0] = malloc(src_len + 1);
        strcpy(dest[0], src);
        return 1;
    }

    for (int i = 0; i < src_len; i++) {
        bool is_match = true;
        // 从当前位置检查是否完整匹配分隔符
        for (int j = 0; j < split_len; j++) {
            if (i + j >= src_len || src[i + j] != splitStr[j]) {
                is_match = false;
                break;
            }
        }

        if (is_match) {
            // 匹配到分隔符,将当前缓冲区内容存入结果数组
            buffer[buf_pos] = '\0';
            dest[counter] = malloc(buf_pos + 1);
            strcpy(dest[counter], buffer);
            counter++;
            buf_pos = 0; // 重置缓冲区写入位置
            i += split_len - 1; // 跳过分隔符所占长度
        } else {
            // 未匹配到分隔符,将当前字符写入临时缓冲区
            buffer[buf_pos++] = src[i];
        }
    }

    // 写入最后一段剩余内容
    buffer[buf_pos] = '\0';
    dest[counter] = malloc(buf_pos + 1);
    strcpy(dest[counter], buffer);
    counter++;

    return counter;
}

正确调用示例

int main() {
    const char *src = "Hello;;world;;!";
    // 按指针大小分配结果数组空间,这里预留10个char*位置足够常规场景使用
    char **buffer = malloc(sizeof(char*) * 10);
    int count = split(buffer, src, ";;");
    
    // 打印结果、释放内存
    for (int i = 0; i < count; i++) {
        printf("%s\n", buffer[i]);
        free(buffer[i]);
    }
    free(buffer);
    return 0;
}

运行代码将输出预期结果:

Hello
world
!

内容的提问来源于stack exchange,提问作者T.Naz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 19:24:23