CS50实验2代码问题求助:无论输入何种内容均显示平局
解决CS50 Lab2单词得分计算问题
问题现象
完成CS50实验2时,代码可运行但存在异常:输入提示正常显示,但无论输入什么内容,结果始终为平局。
原代码
#include <ctype.h> #include <cs50.h> #include <stdio.h> #include <string.h> // Points assigned to each letter of the alphabet int POINTS[] = {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 compute_score(string word1, string word2); int main(void) { int i=0, j=0; // Get input words from both players string word1 = get_string("Player 1: "); string word2 = get_string("Player 2: "); // Convert to uppercase int toupper(int word1); int toupper(int word2); // Score both words int score = compute_score(word1, word2); // TODO: Print the winner if (score == 1) { printf("Player 1 Wins!"); } else if (score == 2) { printf("Player 2 Wins!"); } else { printf("Tie!"); } printf("\n"); } int compute_score(string word1, string word2) { int i, j, k, n1=strlen(word1), n2=strlen(word2), p1=0, p2=0; const int alphabetSize = 26; char letters[] = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'}; for (i=0; i<n1 + n2; i++) { for (j=0; j<alphabetSize; j++) { if (letters[j] == word1[i]) { p1 += POINTS[j]; } } for (k=0; k<alphabetSize; k++) { if (letters[k] == word2[i]) { p2 += POINTS[k]; } } } if (p1 > p2) { return 1; } else if (p1 < p2) { return 2; } else { return 3; } }
错误分析
- 大小写转换无效:
int toupper(int word1);是函数声明而非调用,toupper仅处理单个字符,需遍历每个字符完成转换,否则输入小写字母时无法与letters数组中的大写字母匹配,得分始终为0。 - 循环逻辑错误:
for(i=0; i<n1 + n2; i++)会导致索引超出单词长度,访问内存垃圾值,且无法正确遍历两个单词的所有字符,最终得分计算错误。 - 字符匹配冗余且易出错:手动定义
letters数组进行匹配效率低,且未处理非字母字符的情况。
修复后的代码
#include <ctype.h> #include <cs50.h> #include <stdio.h> #include <string.h> // Points assigned to each letter of the alphabet int POINTS[] = {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 compute_score(string word1, string word2); int main(void) { // Get input words from both players string word1 = get_string("Player 1: "); string word2 = get_string("Player 2: "); // Convert to uppercase for (int i = 0; word1[i] != '\0'; i++) { word1[i] = toupper(word1[i]); } for (int i = 0; word2[i] != '\0'; i++) { word2[i] = toupper(word2[i]); } // Score both words int score = compute_score(word1, word2); // Print the winner if (score == 1) { printf("Player 1 Wins!"); } else if (score == 2) { printf("Player 2 Wins!"); } else { printf("Tie!"); } printf("\n"); } int compute_score(string word1, string word2) { int p1 = 0, p2 = 0; // Calculate score for Player 1 for (int i = 0; word1[i] != '\0'; i++) { if (isalpha(word1[i])) { int index = word1[i] - 'A'; p1 += POINTS[index]; } } // Calculate score for Player 2 for (int i = 0; word2[i] != '\0'; i++) { if (isalpha(word2[i])) { int index = word2[i] - 'A'; p2 += POINTS[index]; } } if (p1 > p2) { return 1; } else if (p1 < p2) { return 2; } else { return 3; } }
修复说明
- 替换无效的大小写转换代码,通过循环遍历每个字符完成大写转换;
- 拆分循环,分别遍历两个单词计算得分,避免索引越界;
- 利用ASCII码直接计算字母在
POINTS数组中的索引,简化匹配逻辑,同时通过isalpha过滤非字母字符;
内容的提问来源于stack exchange,提问作者aidiotwholikescoding
相关产品推荐
相关产品推荐

