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

C语言按空格拆分字符串为子串数组运行异常原因求解

代码未按预期运行的核心原因
  • 指针未分配内存:你声明的char *array[5]只是一个存储5个字符指针的数组,每个指针都没有指向合法的可写内存空间,直接调用strncpy往野指针地址写入数据属于未定义行为,轻则输出乱码,重则程序直接崩溃。
  • 字符串未补结束符:strncpy不会自动给目标字符串追加\0结束符,C语言中必须以\0结尾的字符序列才能被%s格式符正常识别为字符串,否则打印时会持续向后读内存直到遇到随机的\0,出现乱码。
  • 断点逻辑不完整:原字符串一共有5个空格,对应5个断点索引,你目前的拆分循环只处理到i<4,只拆分了前4个空格之间的内容,最后一个姓名Micheal从最后一个断点到字符串结尾的部分完全没有处理,且复制内容会包含多余的前置空格。
  • 固定遍历长度风险:你后续遍历breakPoints和array都用了固定的长度值,如果原字符串的空格数量发生变化,就会访问到数组未初始化的元素,触发额外的未定义行为。
修正后的参考代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main() {
    char string [] = " Joe James John Maria Micheal";
    int breakPoints[10]; // 预留足够的断点存储空间
    char ch = ' ';
    int counter = 0;
    int str_len = strlen(string);

    // 收集所有空格断点
    for (int i = 0; i < str_len; i++) {
        if (string[i] == ch) {
            breakPoints[counter] = i;
            counter++;
        }
    }
    // 把字符串末尾也作为最后一个断点,方便统一处理最后一个姓名
    breakPoints[counter] = str_len;
    counter++;

    // 打印断点
    for (int i = 0; i < counter; i++) {
        printf("%d ", breakPoints[i]);
    }
    printf("\n");

    char *array[5];
    int name_count = counter - 1;
    for (int i = 0; i < name_count; i++) {
        int sub_len = breakPoints[i+1] - breakPoints[i];
        // 给每个姓名分配内存,多留1位存结束符
        array[i] = (char*)malloc(sub_len);
        // 跳过空格复制内容
        strncpy(array[i], string + breakPoints[i] + 1, sub_len - 1);
        // 手动补结束符
        array[i][sub_len - 1] = '\0';
    }

    // 打印姓名
    for (int i = 0; i < name_count; i++) {
        printf("%s ", array[i]);
    }
    printf("\n");

    // 释放申请的内存避免泄漏
    for (int i = 0; i < name_count; i++) {
        free(array[i]);
    }
    
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 14:36:08