所以我为 CS50 第 2 周的实验室的拼字游戏问题编写了这段代码。其要点是,我们需要编写代码来计算两个玩家给出的两个单词的分数,然后根据分配给两个单词中每个字母的分数来宣布获胜者。分配给每个字母的点在数组“POINTS”中给出。
如果您需要更多信息,这里是问题的链接:https://cs50.harvard.edu/x/2023/labs/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 };
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");
}
}
如果我只使用普通单词,代码就可以正常工作。但一旦我使用像
question?
这样结尾带有符号的单词,分数就会变得太高,并且无法按预期工作。我的代码处理符号的方式似乎存在一些问题。我知道 isupper()
是一种更好的实现方式,不会出现任何错误,但我想知道这里到底出了什么问题。
在
compute_score
中,您可以通过 POINTS[upper_word[i] - 65];
访问给定图块的分数。 如果偏移量 i
处的字符不是大写字母,则计算为 upper_word[i] - 65
的索引超出了数组 POINTS
的范围,因此访问此条目具有未定义的行为。请注意,您假设大写字母在字符集中是连续的,并且 A
被编码为 65
,这是 ASCII 特有的。该程序将在使用 EBCDIC 的目标上失败(但您不太可能找到一个)。
您应该拒绝不完全由字母组成的单词,可能还有一些通配符,例如
*
或
作为占位符。
这是修改后的版本:
#include <cs50.h>
#include <ctype.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++) {
unsigned char cc = word[i];
word[i] = toupper(cc);
}
printf("%s\n", word);
return word;
}
int compute_score(string upper_word)
{
// Add score for each letter
int length = strlen(word);
int score = 0;
for (int i = 0; i < length; i++) {
unsigned char cc = upper_word[i];
if (!isupper(cc)) {
if (cc != ' ' && cc != '*') {
printf("invalid word: %s\n", upper_word);
return 0;
}
} else {
score = score + POINTS[cc - 'A'];
}
}
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");
}
}
#include <cs50.h>
#include <stdio.h>
#include <string.h>
int calculateTotalScore(string value);
string convertToUpperCase(string value);
int Points[26] = {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 main(void)
{
string player1 = get_string("Player 1: ");
string player2 = get_string("Player 2: ");
string upperCasePlayer1 = convertToUpperCase(player1);
string upperCasePlayer2 = convertToUpperCase(player2);
int player1Score = calculateTotalScore(upperCasePlayer1);
int player2Score = calculateTotalScore(upperCasePlayer2);
if (player1Score > player2Score)
{
printf("Player 1 wins!\n");
}
else if (player2Score > player1Score)
{
printf("Player 2 wins!\n");
}
else
{
printf("Tie!\n");
}
}
int calculateTotalScore(string value)
{
int score = 0;
for (int i = 0, length = strlen(value); i < length; i++)
{
if (value[i] >= 'A' && value[i] <= 'Z')
{
score = score + Points[value[i] - 'A'];
}
}
return score;
}
string convertToUpperCase(string value)
{
for (int i = 0, length = strlen(value); i < length; i++)
{
if (value[i] >= 'a' && value[i] <= 'z')
{
value[i] = (value[i] - 32);
}
}
return value;
}
#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(void)
{
// 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 (score2>score1)
printf("Player 2 wins\n");
else printf("Tie!\n");
}
int compute_score(string word)
{
// TODO: Compute and return score for string
int sum=0;
// loop to iterate across string
for(int i=0;i<strlen(word);i++)
{
//reject all the characters that come before letters in ascii chart
//make them 0 so that they dont add up the score and return garbage value
if(word[i]>=1 &&word[i]<=64)
{
word[i]=0;
}
//convert all to uppercase so we dont have to check twice
word[i]=toupper(word[i]);
int a=word[i]-'A';
// counter
sum=sum+POINTS[a];
}
return sum;
}
// anant 代码