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

CS50第二周Scrabble计分代码符号处理异常,求错误根源

CS50 Scrabble代码符号输入异常的原因分析

你编写的CS50第二周Scrabble实验代码,在输入含符号的单词(如question?)时得分异常偏高,核心原因是数组越界访问导致的未定义行为,具体拆解如下:

问题代码

#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 };

string convert_upper(string word);
int compute_score(string upper_word);
void print_winner(int score1, int score2);

int main(void)
{
    // Get input words from both players
    string word1 = get_string("Player 1: ");
    string word2 = get_string("Player 2: ");

    // Convert to uppercase
    string upper_word1 = convert_upper(word1);
    string upper_word2 = convert_upper(word2);

    // Calculate scores
    int score1 = compute_score(upper_word1);
    int score2 = compute_score(upper_word2);

    // TODO: Print the winner
    print_winner(score1, score2);
}

string convert_upper(string word)
{
    // Convert to uppercase
    int length = strlen(word);
    for (int i = 0; i < length; i++)
    {
        word[i] = toupper(word[i]);
    }
    printf("%s\n", word);
    return word;
}

int compute_score(string upper_word)
{
    // Add score for each letter
    int score = 0;
    for (int i = 0; i < strlen(upper_word); i++)
    {
        score = score + POINTS[upper_word[i]-65];
    }
    return score;
}

void print_winner(int score1, int score2)
{
    // Print result based on the scores
    if (score1 > score2)
    {
        printf("Player 1 wins \n");
    }
    else if (score2 > score1)
    {
        printf("Player 2 wins \n");
    }
    else
    {
        printf("Tie! \n");
    }
}

错误原因详解

  1. 非字母字符的ASCII值处理问题
    toupper()函数仅对字母字符生效,对于?这类非字母符号,处理后其ASCII值保持不变(比如?的ASCII是63)。

  2. 数组越界访问
    在compute_score函数中,你通过upper_word[i]-65计算数组索引:

    • 对于大写字母A-Z,ASCII值范围是65-90,计算后索引为0-25,正好匹配POINTS数组的有效索引(数组共26个元素,索引0到25)。
    • 对于非字母符号,比如?,63-65=-2,这是一个负数索引;如果是其他符号(比如!的ASCII是33,33-65=-32),同样会得到超出0-25范围的索引。
  3. 未定义行为导致的异常得分
    C语言不允许数组越界访问,此时程序会读取数组内存范围之外的随机垃圾值。这些垃圾值通常是较大的整数,直接加到得分中就会导致总分异常偏高,甚至可能引发程序崩溃。

为什么isupper()能解决问题

用isupper()(或先通过isalpha()判断是否为字母)可以筛选出仅属于A-Z的字符,只有符合条件的字符才参与分数计算,跳过非字母符号,从根源避免了数组越界的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 07:15:09