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

CS50 Week2拼字游戏compute_score函数无法处理标点符号求助

CS50第二周拼字游戏:含标点输入的得分计算问题

我在完成CS50第二周的简易拼字游戏作业时,自定义函数int compute_score(string word)无法正确处理包含标点的输入。我尝试通过将所有输入转为大写来简化逻辑,代码行数更少,逻辑上和正确答案相近,但用check50测试时,仅纯标点的用例未通过。

我的核心代码如下:

#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 word);

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

    // Score both words
    int score1 = compute_score(word1);
    int score2 = compute_score(word2);

    // Print the winner
    if (score1 > score2)
    {
        printf("Player 1 wins!\n");
    }
    else if (score1 < score2)
    {
        printf("Player 2 wins!\n");
    }
    else
    {
        printf("Tie!\n");
    }
}

int compute_score(string word)
{
    // Compute and return score for string
    int score = 0;

    // Convert array of chars to uppercase and calculate score
    for (int i = 0, N = strlen(word); i < N; i++)
    {
        score = score + POINTS[toupper(word[i]) - 65];
    }
    return score;
}

我原本以为toupper仅对字母生效,标点会被忽略、贡献0分,但实际并非如此。正确答案的核心循环代码如下:

for (int i = 0, N = strlen(word); i < N; i++)
{
    if (isupper(word[i]))
    {
        score += POINTS[word[i] - 'A'];
    }
    else if (islower(word[i]))
    {
        score += POINTS[word[i] - 'a'];
    }
}

问题原因

关键在于:当输入是标点(或其他非字母字符)时,toupper(word[i])不会返回字母表范围内的ASCII值。比如标点!的ASCII是33,toupper(33)返回的还是33,此时33 - 65 = -32,访问POINTS[-32]属于数组越界访问,会读取内存中的随机值,导致得分错误,而不是预期的0分。

解决建议

修改compute_score函数,先判断字符是否为字母,再进行得分计算,非字母字符直接跳过:

方法一:通过ASCII范围判断

int compute_score(string word)
{
    int score = 0;
    for (int i = 0, N = strlen(word); i < N; i++)
    {
        char upper_c = toupper(word[i]);
        // 仅处理A-Z范围内的大写字母
        if (upper_c >= 'A' && upper_c <= 'Z')
        {
            score += POINTS[upper_c - 'A'];
        }
        // 非字母字符不做处理,跳过
    }
    return score;
}

方法二:使用isalpha函数判断

int compute_score(string word)
{
    int score = 0;
    for (int i = 0, N = strlen(word); i < N; i++)
    {
        // 先判断是否为字母字符
        if (isalpha(word[i]))
        {
            char upper_c = toupper(word[i]);
            score += POINTS[upper_c - 'A'];
        }
    }
    return score;
}

这两种方式都会跳过非字母字符,纯标点输入的得分会是0,符合check50的测试要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 03:57:00