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

为何C语言字符串分割代码在非空格结尾时输出多余字符?

C语言字符串分割出现多余随机字符的问题分析

问题描述

编写了用于分割字符串为单词的C语言代码,运行后输出出现多余的随机字符,例如测试输入"abcd efgh! ijkl mnop"时,输出多了一个P,其他测试用例也有类似问题。代码及输出如下:

代码

void form_rule2(char * str)
{
    int num_words=0;
    char word[20];
    while(sscanf(str,"%s",word)==1)
    {
        num_words++;
        printf("%s\n",word);

        str+=strlen(word)+1;
    }

}

void main()
{
    form_rule2("abcd efgh! ijkl mnop");
}

运行输出

abcd
efgh!
ijkl
mnop
P

问题根源

核心问题是指针越界访问未定义内存区域,和NULL终止符直接相关:

  1. 字符串字面量"abcd efgh! ijkl mnop"在内存中以\0结尾,当处理完最后一个单词mnop后,str += strlen(word)+1会让指针指向mnop末尾\0的下一个位置,这已经超出了该字符串字面量的内存范围。
  2. 此时sscanf会读取越界后的随机内存数据,这些数据可能包含可打印字符,就会出现多余的输出,属于C语言中的未定义行为。
  3. 另外,str += strlen(word)+1的逻辑本身存在漏洞:如果单词之间有多个空白字符(比如多个空格),该代码只会跳过一个字符,后续sscanf会自动忽略空白,但最终越界的问题依然存在。

修正方案

方案1:安全遍历指针,避免越界

使用临时指针遍历字符串,跳过空白字符,确保指针不会超出字符串范围:

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

void form_rule2(const char *str) {
    int num_words = 0;
    char word[20];
    const char *ptr = str;
    while (sscanf(ptr, "%s", word) == 1) {
        num_words++;
        printf("%s\n", word);
        // 移动指针到当前单词末尾
        ptr += strlen(word);
        // 跳过所有连续空白字符
        while (*ptr != '\0' && isspace((unsigned char)*ptr)) {
            ptr++;
        }
        // 到达字符串末尾则终止循环
        if (*ptr == '\0') {
            break;
        }
    }
}

int main() {
    form_rule2("abcd efgh! ijkl mnop");
    return 0;
}

方案2:使用标准库函数strtok

strtok是C标准库中专门用于字符串分割的函数,更简洁可靠:

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

void form_rule2(char *str) {
    int num_words = 0;
    // 按空白字符(空格、制表符、换行符)分割字符串
    char *word = strtok(str, " \t\n");
    while (word != NULL) {
        num_words++;
        printf("%s\n", word);
        word = strtok(NULL, " \t\n");
    }
}

int main() {
    // 字符串字面量不可修改,需复制到可写栈数组中
    char str[] = "abcd efgh! ijkl mnop";
    form_rule2(str);
    return 0;
}

额外注意事项

  • 字符串字面量属于只读内存,不能直接修改,也不要访问其末尾\0之外的内存。
  • main函数的标准返回类型是int,而非void,gcc编译器会对void main()发出警告,建议改为标准写法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 17:35:29