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

如何在C语言中实现忽略单双引号内内容的字符串分割函数?

实现忽略引号内分隔符的split函数

我自己重写了一个按指定分隔符分割字符串的split函数,想要修改它,让它忽略单引号或双引号内的分隔符,但始终没能实现预期效果。尝试用标志位处理引号状态,但逻辑过于复杂,导致部分测试用例通过,其他用例失败。

原调试代码

void    quote_state(char c , int *inquotes) // 检查引号状态
{
    if (c == '\'' || c == '\"')
    {
        if(!(*inquotes))
            *inquotes = 1;
        else if (*inquotes == 1)
            *inquotes = 0;
    }
}

char    **ft_split2(char *s, char c)
{
    char **str;
    int    i;
    int    j;
    int start;
    int    inquotes;

    // 分配所需内存
    //...

    while (s[j])
    {
        while (s[j] == c && !inquotes)
            j++;
        start = j;
        quote_state(s[j], &inquotes);
        while (s[j] != c && s[j])
        {
            quote_state(s[j], &inquotes);
            j++;
            if (inquotes)
                break;
        }
        if ((s[j] == "\"" || s[j] == "\'") && inquotes)
            j++;
        if (j > start)
            str[i++] = wordp(s, start, j); // 分配内存并存储元素.. 
    }
    str[i] = NULL
    return(str);
}

测试用例

  • 输入字符串:" kaka koko " waah waah " lla "
  • 当前输出:kaka\0koko\0"\0waah waah "\0lla\0
  • 期望输出:kaka\0koko\0" waah waah "\0lla\0NULL

问题分析与修正方案

原代码存在几个关键问题:

  1. 引号转义错误:C语言中双引号直接用'"'表示,无需转义成'\"';字符串比较== "\""是错误的,应该用字符比较== '"'。
  2. 变量未初始化:inquotes、i、j等变量没有初始值,会导致未定义行为。
  3. 引号状态逻辑错误:内层循环遇到引号就break,无法完整遍历引号内的内容;且未区分当前处于单引号还是双引号,无法正确处理引号闭合。
  4. 单词截取逻辑混乱:没有正确处理引号的开始和结束位置,导致截取内容不符合预期。

修正后的代码

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

// 辅助函数:计算分割后的单词数量
static int count_words(char *s, char c) {
    int count = 0;
    int in_quotes = 0;
    char quote_type = 0;
    int i = 0;

    while (s[i]) {
        // 跳过不在引号内的分隔符
        while (s[i] == c && !in_quotes)
            i++;
        if (s[i] == '\0')
            break;
        count++;
        // 遍历到单词结束(遇到分隔符且不在引号内,或字符串结束)
        while (s[i]) {
            if ((s[i] == '\'' || s[i] == '"') && !in_quotes) {
                in_quotes = 1;
                quote_type = s[i];
            } else if (s[i] == quote_type && in_quotes) {
                in_quotes = 0;
                quote_type = 0;
            }
            if (s[i] == c && !in_quotes)
                break;
            i++;
        }
    }
    return count;
}

// 辅助函数:截取子字符串
static char *wordp(char *s, int start, int end) {
    char *word = malloc(end - start + 1);
    if (!word)
        return NULL;
    strncpy(word, s + start, end - start);
    word[end - start] = '\0';
    return word;
}

char **ft_split2(char *s, char c) {
    if (!s)
        return NULL;

    int word_count = count_words(s, c);
    char **str = malloc((word_count + 1) * sizeof(char *));
    if (!str)
        return NULL;

    int i = 0; // 结果数组索引
    int j = 0; // 原字符串索引
    int start;
    int in_quotes = 0;
    char quote_type = 0;

    while (s[j]) {
        // 跳过不在引号内的分隔符
        while (s[j] == c && !in_quotes)
            j++;
        if (s[j] == '\0')
            break;
        start = j;
        // 遍历到当前单词结束
        while (s[j]) {
            // 更新引号状态
            if ((s[j] == '\'' || s[j] == '"') && !in_quotes) {
                in_quotes = 1;
                quote_type = s[j];
            } else if (s[j] == quote_type && in_quotes) {
                in_quotes = 0;
                quote_type = 0;
            }
            // 遇到分隔符且不在引号内,结束当前单词
            if (s[j] == c && !in_quotes)
                break;
            j++;
        }
        // 截取并存储单词
        str[i++] = wordp(s, start, j);
    }
    str[i] = NULL;
    return str;
}

关键修正点说明

  1. 精准处理引号状态:用quote_type记录当前处于单引号还是双引号,确保只有遇到相同类型的引号时才退出引号状态,避免误判。
  2. 变量明确初始化:所有变量都赋予初始值,杜绝未定义行为。
  3. 完善单词计数逻辑:先遍历字符串统计单词数量,确保内存分配准确。
  4. 清晰的遍历逻辑:先跳过分隔符,再完整遍历引号内的内容,直到遇到闭合引号或字符串结束,最后截取正确的子字符串。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 08:10:16