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

C语言实现长字符串分割为单个单词的问题求助

问题分析与解决方案

原代码的核心问题

  • scanf("%s", bigString) 无法读取带空格的完整字符串:%s 会在第一个空白符(空格、换行、制表符)处停止读取,导致 bigString 仅存储第一个单词,后续内容完全丢失。
  • 未添加字符串终止符:C语言中字符串必须以 '\0' 结尾,原代码将字符存入数组后未补充该终止符,printf("%s") 会越界读取内存,最终输出乱码。
  • 循环逻辑漏洞:检测到字符串末尾 '\0' 时设置 i=10 退出循环,但后续仍执行 bigIndex++,此时 bigIndex 已指向字符串终止位置,造成越界访问;且退出循环时 printf("%s", wordCollection[i]) 会访问 wordCollection[10],超出数组有效索引范围(0-9)。

修正后的基础实现代码

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

int main()
{
    char bigString[1000];
    // 用fgets读取含空格的完整字符串,手动去除末尾换行符
    fgets(bigString, sizeof(bigString), stdin);
    size_t len = strlen(bigString);
    if (len > 0 && bigString[len-1] == '\n') {
        bigString[len-1] = '\0';
    }

    char wordCollection[10][100];
    int bigIndex = 0;
    int smallIndex = 0;
    int wordCount = 0;

    while (bigString[bigIndex] != '\0' && wordCount < 10) {
        // 跳过连续空格,兼容多空格分隔场景
        while (bigString[bigIndex] == ' ') {
            bigIndex++;
        }
        // 读取单个单词
        smallIndex = 0;
        while (bigString[bigIndex] != ' ' && bigString[bigIndex] != '\0') {
            wordCollection[wordCount][smallIndex] = bigString[bigIndex];
            bigIndex++;
            smallIndex++;
        }
        // 添加字符串终止符并打印
        if (smallIndex > 0) {
            wordCollection[wordCount][smallIndex] = '\0';
            printf("%s\n", wordCollection[wordCount]);
            wordCount++;
        }
    }

    return 0;
}

基于指针的高效实现思路

方法1:使用标准库函数strtok

strtok 是C标准库专门用于字符串分割的函数,以指定分隔符拆分字符串,代码简洁高效:

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

int main()
{
    char bigString[1000];
    fgets(bigString, sizeof(bigString), stdin);
    size_t len = strlen(bigString);
    if (len > 0 && bigString[len-1] == '\n') {
        bigString[len-1] = '\0';
    }

    char wordCollection[10][100];
    int wordCount = 0;
    // 第一次调用传入原字符串,指定空格为分隔符
    char* token = strtok(bigString, " ");

    while (token != NULL && wordCount < 10) {
        // 复制单词到数组,确保不越界
        strncpy(wordCollection[wordCount], token, sizeof(wordCollection[wordCount])-1);
        wordCollection[wordCount][sizeof(wordCollection[wordCount])-1] = '\0';
        printf("%s\n", wordCollection[wordCount]);
        wordCount++;
        // 后续调用传入NULL,继续分割原字符串
        token = strtok(NULL, " ");
    }

    return 0;
}

注意:strtok 会修改原字符串,若需保留原内容,需先复制一份再分割。

方法2:手动指针遍历

不依赖库函数,直接用指针操作字符串,灵活性更高:

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

int main()
{
    char bigString[1000];
    fgets(bigString, sizeof(bigString), stdin);
    size_t len = strlen(bigString);
    if (len > 0 && bigString[len-1] == '\n') {
        bigString[len-1] = '\0';
    }

    char wordCollection[10][100];
    int wordCount = 0;
    char* current = bigString;
    char* wordStart = current;

    while (*current != '\0' && wordCount < 10) {
        // 跳过前置空格
        while (*current == ' ') {
            current++;
            wordStart = current;
        }
        // 定位单词末尾
        while (*current != ' ' && *current != '\0') {
            current++;
        }
        // 计算单词长度并复制
        int wordLen = current - wordStart;
        if (wordLen > 0) {
            // 防止数组越界
            if (wordLen >= sizeof(wordCollection[wordCount])) {
                wordLen = sizeof(wordCollection[wordCount]) - 1;
            }
            strncpy(wordCollection[wordCount], wordStart, wordLen);
            wordCollection[wordCount][wordLen] = '\0';
            printf("%s\n", wordCollection[wordCount]);
            wordCount++;
        }
    }

    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 05:35:25