我正在C中创建一个Hangman项目,其中要猜测的单词用破折号表示,随着游戏的进行,这些破折号被正确的猜测所取代。我使用了一个链表来存储所有的单词。我已经弄清楚了几乎所有的功能,然而,我最新版本的游戏运行得很完美,除非单词中有一个重复出现的角色需要猜测。之所以会出现这种情况,是因为我创建了一个函数,该函数接受用户的猜测,并将其与秘密单词进行比较。如果对"0"的特定索引的猜测是正确的;秘密";字符串,它将破折号的char数组的索引设置为相同的猜测(并显示破折号供玩家猜测(。问题是短划线字符串是一个数组,如果一个字符出现两次,就会弄乱短划线的长度。
我不知道以后该怎么办。有没有办法将重复值存储在两个不同的索引中,或者我应该尝试不同的方法来存储字符串?此外,如果问题令人困惑,阅读程序并稍微理解代码可能会有所帮助。我在每个函数处都用注释格式化了它,所以即使我的代码有点乱,也不会太难理解。我们非常感谢所有的帮助。
链接到words.txt文件,以防您需要
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
int nodeNum, chances, misses, score, corrGuess;
char* secret;
char incorrGuess[50], guess, dashes[];
/*Node of linked list*/
typedef struct node {
char *data;
struct node *next;
} node;
node *start = NULL;
node *current;
/*Appending nodes to linked list*/
void add(char *line) {
node *temp = malloc(sizeof(node));
temp->data = strdup(line);
temp->next = NULL;
current = start;
if(start == NULL) {
start = temp;
} else {
while(current->next != NULL) {
current = current->next;
}
current->next = temp;
}
}
/*read text file*/
void readfile(char *filename) {
FILE *file = fopen(filename, "r");
if(file == NULL) {
exit(1);
}
char buffer[512];
while(fgets(buffer, sizeof(buffer), file) != NULL) {
add(buffer);
}
fclose(file);
}
/*Set initial dashes string*/
void setInitDash(){
int i;
for(i=0; i < strlen(secret)-1; i++){
dashes[i] = '-';
}
}
/*Generate random number between 0 and 2999*/
void randNum(int lower, int upper)
{
srand(time(0));
nodeNum = (rand() % (upper - lower + 1)) + lower;
}
/*Choose random node based on random number generated*/
void chooseRand(struct node* start)
{
node* p;
int n;
p = start;
for(n = 0; n != nodeNum; n++)
{
p = p->next;
}
secret = p->data;
setInitDash();
}
/*Check guess for correct guess*/
void checkGuess(){
int i, j = strlen(secret) - 1;
for(i = 0; i != j; i++){
if(secret[i] == guess) {
dashes[i] = guess;
score++;
}
}
}
/*Check if score changes*/
void checkScore(){
if(score == 0){
misses++;
chances--;
incorrGuess[misses] = guess;
}
else{
score = 0;
}
printf("%s", dashes);
}
/*Print current board*/
void printBoard(){
printf("__________________________________________________________________n");
printf("nnCurrent Word: ");
checkGuess();
checkScore();
printf(" Chances: %d Incorrect Guesses: ", chances);
for(int i = 0; i <= misses; i++)
printf("%c", incorrGuess[i]);
printf("nPlease enter your guess: ");
scanf(" %c", &guess);
printf("n__________________________________________________________________n");
}
/*Function for if player wins*/
void winCase(){
printf("nnnnnGood Job! You have guessed the word correctly. Restart the program to play again!");
}
/*Function for if player loses*/
void loseCase(){
printf("nnnnnUnfortunately, you have run out of chances. The word to guess was %s.", secret);
}
int main(){
int i;
score = 0;
corrGuess = score;
int stillPlaying = 1;
printf("Hello User, Welcome to HangmannPlease enter number of chances you would like: "); /*Welcome Message*/
scanf("%d", &chances);
readfile("words.txt"); /*Readfile and choose random word*/
randNum(0, 2999);
chooseRand(start);
printf("%s", secret); /*Print secret word for easy testing*/
printf("__________________________________________________________________n"); /*Print first iteration of the board*/
printf("nnCurrent Word: %s", dashes);
printf(" Chances: %d Incorrect Guesses: %s", chances, incorrGuess);
printf("nPlease enter your guess: ");
scanf(" %c", &guess);
printf("n__________________________________________________________________n");
while(stillPlaying == 1){ /*While loop to print board until win or lose case is true*/
printBoard();
if(dashes == secret){
stillPlaying = 2;
}
else if(chances <= 0){
stillPlaying = 0;
}
}
if(stillPlaying == 0){
loseCase();
}
else if(stillPlaying == 2){
winCase();
}
return 0;
}
您从未初始化过"短划线"。给它一个尺寸,你应该很好。我接通了50的电源,仪表板的更换效果很好。**编辑**仔细想想,我建议使用malloc/caloc/realloc。因此,将破折号声明为:
char *dashes;
然后当你需要使用它时,分配空间:
void setInitDash() {
int i;
// calloc fills the space with 0x00, ensuring that your string has a null terminator
dashes = calloc(strlen(secret) + 1, sizeof(char);
//I don't know why you had strlen(secret-1), strlen ignores the null terminator
for(i = 0; i < strlen(secret); i++) {
dashes[i] = 'i';
}
}
这个代码的另一个大问题:
if(dashes == secret)
将始终计算为FALSE,因为它比较的是地址破折号和机密点,而不是值。要比较字符串,您需要比较每个单独的数组成员,或者使用string.h 中的strcmp函数