字符串单词计数函数故障排查:自动测试未通过求助
单词统计函数的问题分析与修复方案
嘿,我来帮你搞定这个问题!你的测试输入应该统计出38个单词,但当前函数只返回32,核心问题出在指针操作混乱和单词判断逻辑的漏洞上,咱们一步步拆解:
现有代码的致命问题
- 指针跳步导致字符遗漏:你在条件判断里用了
*(++str),这会直接把指针往前挪一位,而循环末尾又执行了str++——等于一次循环跳过了两个字符!很多单词的开头或中间字符根本没被检查到,统计自然少了。 - 逻辑判断逻辑混乱:你的条件试图在“非字母后接字母”或“开头是字母”时计数,但这种组合不仅优先级容易出错,还会漏掉很多符号分隔的单词(比如
mission:后面的to,你的逻辑就没正确识别)。 - 没有跟踪单词状态:你只靠计数器和当前字符判断,没法区分“连续字母”和“新单词开头”,很容易重复计数或者漏计数。
修复思路:用状态跟踪法统计单词
统计单词的靠谱思路是:用一个变量跟踪当前是否处于单词中,当从“非单词状态”切换到“单词状态”时,计数器加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
相关产品推荐
相关产品推荐

