我正在尝试在 cs50 pset 第 2 周中做一个简单的拼字游戏,并且函数 intcompute_score(string word)
无法处理使用标点符号的输入,即使它是通过将所有输入转换为大写,使用更少的代码行与正确答案大致相同。下面是代码,但您真正需要查看的是我上面命名的函数:
#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);
// TODO: 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)
{
// TODO: Compute and return score for string
//Initialize score
int score = 0;
//Convert array of chars to uppercase and solve
for (int i = 0, N = strlen(word); i < N; i++)
{
score = score + POINTS[toupper(word[i]) - 65];
}
return score;
}
在此之前,我在单个字符上使用 toupper
时遇到了麻烦,直到我观看了一个视频,该视频解释了使用 ASCII 图表的逻辑以及如何在讲座中迭代字符串中的字符。所以在 for 循环中,我写道:
//Convert array of chars to uppercase and solve
for (int i = 0, N = strlen(word); i < N; i++)
{
score = score + POINTS[toupper(word[i]) - 65];
}
return score;
我决定将输入转换为全部大写,因为 A
和 g
等字符与其大写/非大写对应的值具有相同的值,我我认为将其转换为大写会更简单,这样逻辑就更简单、更快、更有效。在我的脑海中也更有意义。但是,当我使用 check50 时,除了带有标点符号的内容(最后有一个异常(exception))之外,所有内容都会变成绿色。以下是终端测试显示的内容:
现在我根本不明白这一点,因为在我眼中,它几乎与正确答案完全相同,那就是:
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
被设计为仅适用于字母字符,因此它应该排除特殊字符,将其值呈现为零。有人对出了什么问题有什么建议吗?
最佳答案
… toupper is designed to only work with alphabetical characters, it should be excluding special characters, rendering their value to zero.
toupper
不会更改非字母字符。 toupper('!')
的计算结果与 '!
' 相同,而不是零。 toupper
在 C 2018 76.4.2.2 中指定,其中第 3 段表示(添加粗体):
If the argument is a character for which
islower
is true and there are one or more corresponding characters, as specified by the current locale, for whichisupper
is true, thetoupper
function returns one of the corresponding characters (always the same one for any given locale); otherwise, the argument is returned unchanged.
即使 toupper
确实为非字母字符生成零,您的表达式 POINTS[toupper(word[i]) - 65]
也会计算为 POINTS[0 - 65]
,这不是您想要的。 (另外,'A'
千万不要写成65
,除非是在字符集之间转换等特殊情况。在普通源代码中,使用'A'
> 为“A”的代码。)
您必须编写代码来测试非字母字符,而不是添加到它们的分数中。
(另请注意,使用 x - 'A'
并不是将字母转换为 0 到 25 之间的值的完全可移植方式,因为 C 标准不要求字母的字符代码是连续的。对于简单的学生项目和您知道使用 ASCII 的情况来说是可以的,但完全可移植的解决方案需要额外的工作。)
关于c - 为什么我的 C 函数无法处理标点符号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75801828/