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

字符串单词计数函数故障排查:自动测试未通过求助

单词统计函数的问题分析与修复方案

嘿,我来帮你搞定这个问题!你的测试输入应该统计出38个单词,但当前函数只返回32,核心问题出在指针操作混乱和单词判断逻辑的漏洞上,咱们一步步拆解:

现有代码的致命问题

  1. 指针跳步导致字符遗漏:你在条件判断里用了*(++str),这会直接把指针往前挪一位,而循环末尾又执行了str++——等于一次循环跳过了两个字符!很多单词的开头或中间字符根本没被检查到,统计自然少了。
  2. 逻辑判断逻辑混乱:你的条件试图在“非字母后接字母”或“开头是字母”时计数,但这种组合不仅优先级容易出错,还会漏掉很多符号分隔的单词(比如mission:后面的to,你的逻辑就没正确识别)。
  3. 没有跟踪单词状态:你只靠计数器和当前字符判断,没法区分“连续字母”和“新单词开头”,很容易重复计数或者漏计数。

修复思路:用状态跟踪法统计单词

统计单词的靠谱思路是:用一个变量跟踪当前是否处于单词中,当从“非单词状态”切换到“单词状态”时,计数器加1。这里的“单词”就是连续的字母序列,任何非字母字符都是分隔符。

修复后的完整代码

#include <ctype.h>

int count_words(const char *str)
{
    int count = 0;
    int in_word = 0; // 标记当前是否在单词里:0=不在,1=在

    while (*str != '\0')
    {
        // 判断当前字符是否为字母,转unsigned char避免isalpha处理负数值
        if (isalpha((unsigned char)*str))
        {
            if (!in_word)
            {
                // 从非单词进入单词,计数器加1
                count++;
                in_word = 1;
            }
        }
        else
        {
            // 遇到非字母,标记为不在单词中
            in_word = 0;
        }
        str++; // 每次循环只移动一次指针,确保每个字符都被检查
    }

    return count;
}

代码细节解释

  • in_word变量是核心:它帮我们区分“连续字母”和“新单词的第一个字母”,避免重复计数同一个单词。
  • 每次循环只移动一次str:确保每个字符都被遍历到,不会像之前那样跳步遗漏。
  • (unsigned char)*str:因为isalpha要求输入是unsigned char或者EOF,如果原字符是负的(比如某些扩展ASCII),转成无符号可以避免未定义行为。

用你提供的测试输入跑这个函数,就能得到预期的38个单词啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 10:35:41