CS50 Lab2:拼字游戏得分计算函数触发Segmentation Fault (Core Dumped)
问题排查与修复方案
核心段错误原因:数组越界访问
你的do-while循环逻辑完全错误,以大写字母判断为例:
z初始值为0,进入do块后先执行z++,此时z=1,再判断word[k] != upletters[z]- 如果当前字符是'A',而
upletters[0]才是'A',这个条件永远成立,z会一直递增,直到超出upletters数组的范围(32),访问非法内存触发段错误。
其他代码问题
- 数组填充不完整:大写字母循环
i < 90会漏掉'Z'(ASCII值90),小写字母循环j < 122会漏掉'z'(ASCII值122),应该改成i <= 90和j <= 122。 - 低效的字符串长度计算:循环条件里每次调用
strlen(word),对于string类型应该直接用word.size(),避免重复计算。 - 字符判断的潜在问题:
isupper和islower的参数如果是有符号char,当字符值为负数时会触发未定义行为,应该先转成unsigned char。
修复后的代码
如果只是按原逻辑取ASCII值累加得分,完全不需要额外存储字母数组,直接简化代码:
#include <cctype> #include <string> int compute_score(std::string word) { int sum = 0; for (char c : word) { if (std::isupper(static_cast<unsigned char>(c))) { sum += c; } else if (std::islower(static_cast<unsigned char>(c))) { sum += c; } // 非字母字符加0,无需额外处理 } return sum; }
如果你的拼字游戏需要按标准规则给不同字母分配分值(比如A=1分、B=3分),更合理的写法是用映射表:
#include <cctype> #include <string> int compute_score(std::string word) { // 标准拼字游戏字母分值表 const int letter_scores[] = { 1, 3, 3, 2, 1, 4, 2, 4, 1, 8, 5, 1, 3, 1, 1, 3, 10, 1, 1, 1, 1, 4, 4, 8, 4, 10 }; int sum = 0; for (char c : word) { if (std::isupper(static_cast<unsigned char>(c))) { sum += letter_scores[c - 'A']; } else if (std::islower(static_cast<unsigned char>(c))) { sum += letter_scores[c - 'a']; } } return sum; }
额外说明
原代码中用数组存储所有字母再逐个匹配的做法完全冗余,通过ASCII值的偏移可以直接定位字母对应的分值,既彻底避免了数组越界问题,又大幅提升了代码的效率和可读性。
内容的提问来源于stack exchange,提问作者nicefaa6taa
相关产品推荐
相关产品推荐

