C++程序bug排查:连续元音单词检测功能异常
问题根源
你的代码出现错误判定的核心原因是循环越界访问了字符串结束符'\0',结合C语言字符串的特性触发了误判:
- 当遍历到单词的最后一个字符时,
i+1指向的是字符串结束符'\0' - 你定义的
voc数组在内存中默认包含末尾的'\0'(C语言字符串以'\0'结尾),所以strchr(voc, '\0')会返回非空指针,导致当单词最后一个字符是元音时,错误触发条件strchr(voc, a) && strchr(voc, b)。
修复后的代码
#include <iostream> #include <cstring> #include <fstream> using namespace std; ifstream in("ex.in"); ofstream out("ex.out"); char t[401], voc[] = "aeiouAEIOU", s[401]; int nr = 0, i; int main() { in.getline(t, 401); char *cuv = strtok(t, " "); // 寻找第一个包含连续两个元音的单词 while(cuv && !nr) { int len = strlen(cuv); // 提前计算长度,避免循环内重复调用 for(i = 0; i < len - 1; i++) // 仅遍历到倒数第二个字符,避免越界 { char a = cuv[i]; char b = cuv[i+1]; if(strchr(voc, a) && strchr(voc, b)) { nr = 1; // 当前单词算1次 strcpy(s, cuv); break; } } cuv = strtok(NULL, " "); } // 统计该单词的总出现次数 while(cuv) { if(strcmp(s, cuv) == 0) nr++; cuv = strtok(NULL, " "); } if(nr == 0) out << "Invalid"; else out << s << " " << nr; return 0; }
关键修改说明
- 修正循环边界:将
for循环的终止条件改为i < len - 1,确保只检查连续的有效字符对,不会访问到字符串结束符'\0'。 - 优化长度计算:提前把单词长度存入
len变量,避免循环每次迭代都调用strlen,提升效率。 - 显式初始化计数变量:将
nr初始化为0,代码逻辑更清晰(全局变量虽默认初始为0,但显式初始化更符合编程规范)。 - 调整初始计数逻辑:找到目标单词时将
nr设为1,因为当前单词本身就是第一次出现,后续循环统计额外出现的次数。
测试输入"vine book bear book"时,修复后的代码会正确跳过无连续元音的vine,找到第一个符合条件的book,并统计其总出现次数为2,输出book 2。
内容的提问来源于stack exchange,提问作者NoobieCodie
相关产品推荐
相关产品推荐

