You need to enable JavaScript to run this app. C语言不调用预制函数按空白符分割字符串为单词数组问题排查
优惠活动
大模型
产品
解决方案
定价
更多

C语言不调用预制函数按空白符分割字符串为单词数组问题排查

ft_split_whitespaces 实现问题排查

需求说明

  • 编写函数将输入字符串按空白符分割为多个单词,返回存储这些单词的数组
  • 分割函数内仅可使用malloc作为预制函数
  • 函数签名必须为char **ft_split_whitespaces(char *str)

问题现象

当前运行输出:

d this is me
    s is me
    s me
    r

预期输出:

Hello
    World
    This
    Is
    Me

现有实现代码

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

int     count_words(char *str)
{
    int i; 
    int word;
    
    i = 0;
    word = 1;
    while(str[i]!='\0')
    {
        if(str[i]==' ' || str[i]=='\n' || str[i]=='\t' 
        || str[i]=='\f' || str[i]=='\r' || str[i]=='\v')
            word++;
        i++;
    }
    return (word);
}

char    **ft_split_whitespaces(char *str)
{
    int index;
    int size;
    int index2;
    char **arr;
    
    index = 0;
    index2 = 0;
    size = count_words(str);
    arr = (char **)malloc(size * sizeof(char));
    if (arr == NULL)
        return ((char **)NULL);
    while (str[index])
    {
        if(str[index] == ' ')
        {
            index++;
            value++;
            index2++;
        }
        else
            *(arr+index2) = (char*) malloc(index * sizeof(char));
            *(arr+index2) = &str[index];    
        index++;
    }
    **arr = '\0';
    return (arr);
}

int main()
{
    char a[] = "Hello World This Is Me";
    char **arr;
    int i;
    int ctr = count_words(a);
    arr = ft_split_whitespaces(a);
    
    for(i=0;i < ctr;i++)
        printf("%s\n",arr[i]);
    return 0;
}

存在的问题

  • count_words计数逻辑错误:初始值设为1不合理,连续空白符、首尾空白符都会导致计数偏大,应该仅在「当前字符非空白且前一个字符是空白」的时候计数+1
  • 指针数组分配错误:arr = (char **)malloc(size * sizeof(char)); 应该用sizeof(char*),指针数组每个元素是字符指针,占4/8字节不是1字节
  • 未定义变量:ft_split_whitespaces中使用了未声明的value变量,属于语法错误
  • 分隔符判断不全:仅判断了空格作为分隔符,没有匹配count_words中定义的其他空白符(换行、制表、换页等)
  • 分支逻辑错误:else分支没有加花括号,导致*(arr+index2) = &str[index]; 无论if条件是否成立都会执行
  • 字符串未独立拷贝:直接把指针指向原字符串地址,没有拷贝单词内容,也没有在单词末尾加\0,会导致输出时连带后续字符串
  • 单词内存分配错误:分配单词内存时用全局遍历的index作为长度,不是当前单词的实际长度
  • 末尾操作逻辑错误:**arr = '\0'; 直接把第一个单词的首字符设为终止符,导致第一个单词输出为空

修复后完整代码

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

// 判断是否是空白符的辅助函数
int is_whitespace(char c) {
    return c == ' ' || c == '\n' || c == '\t' || c == '\f' || c == '\r' || c == '\v';
}

int count_words(char *str) {
    int i = 0;
    int word = 0;
    int in_word = 0;
    while(str[i] != '\0') {
        if (!is_whitespace(str[i]) && !in_word) {
            word++;
            in_word = 1;
        } else if (is_whitespace(str[i])) {
            in_word = 0;
        }
        i++;
    }
    return word;
}

char **ft_split_whitespaces(char *str) {
    int index = 0;
    int word_idx = 0;
    int word_len = 0;
    int size = count_words(str);
    // 多分配一个位置存NULL作为数组结束标记
    char **arr = (char **)malloc((size + 1) * sizeof(char*));
    if (arr == NULL) return NULL;

    while(str[index]) {
        // 跳过空白符
        while (str[index] && is_whitespace(str[index])) {
            index++;
        }
        if (!str[index]) break;
        // 计算当前单词长度
        word_len = 0;
        while (str[index + word_len] && !is_whitespace(str[index + word_len])) {
            word_len++;
        }
        // 分配单词内存:+1存终止符
        arr[word_idx] = (char*)malloc((word_len + 1) * sizeof(char));
        if (arr[word_idx] == NULL) return NULL;
        // 拷贝单词内容
        for (int i = 0; i < word_len; i++) {
            arr[word_idx][i] = str[index + i];
        }
        arr[word_idx][word_len] = '\0';
        word_idx++;
        index += word_len;
    }
    arr[word_idx] = NULL;
    return arr;
}

int main() {
    char a[] = "Hello World This Is Me";
    char **arr = ft_split_whitespaces(a);
    int i = 0;
    while(arr[i]) {
        printf("%s\n", arr[i]);
        i++;
    }
    // 生产环境可在此处添加内存释放逻辑避免泄漏
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 11:57:01