C语言Hangman猜单词程序异常终止求助:输入提示后程序退出
我在用C语言编写Hangman(猜单词)游戏时遇到问题:程序打印出猜字母的提示后立即终止,首次猜测机会出现后没有后续输出。以下是程序代码、操作步骤及运行输出:
程序代码
#include <stdio.h> #include <string.h> int main() { char menu; int c = 0, flag = 0, life = 8; printf("\nWelcome to Hangman!!!"); printf("\nThis is a game of hangman."); printf("Player 1 enters a random word and the other has to guess it."); printf("You get 8 lives in total i.e. you can have a maximum of 8 wrong guesses."); printf("\n"); printf("Press n for new game\n"); printf("Press q to quit\n"); printf("\n"); scanf("%c", &menu); int i = 0, j = 0; char w[20], ch; if (menu == 'q') { printf("Exiting..."); printf("Thanks for playing"); } else if (menu == 'n') { printf("Player 1 enters a word\n"); scanf("%s", w); int len = strlen(w); for (int i = 0; i < len; i++) { toupper(w[i]); } printf("\e[1;1H\e[2J"); char arr[len - 1]; for (int i = 0; i < len - 1; i++) { arr[i] = '_'; printf("%c", arr[i]); } printf("\n"); while (life != 0) { for (int i = 0; i < len - 1; i++) { if (arr[i] == '_') { flag = 1; break; } else { flag = 0; } } if (flag == 0) { printf("You Won!!\n"); printf("You Guessed The Word: %s", w); break; } else { char ans; printf("Enter a letter between A-Z"); scanf("%c", ans); toupper(ans); for (int j = 0; j < len; j++) { if (ans == w[j]) { arr[j] = ans; c++; } } if (c == 0) { life--; } c = 0; for (int j = 0; j < len; j++) { printf("%c", arr[j]); } printf("\n Lives Remaining= %d \n", life); } } if (life == 0) { printf("\n You Lost!!! \n"); printf("The Word Was: %s", w); } } else { printf("Invalid Character"); } }
运行输出
Welcome to Hangman!!!
This is a game of hangman.Player 1 enters a random word and the other has to guess it.You get 8 lives in total i.e. you can have a maximum of 8 wrong guesses.
Press n for new game
Press q to quit
n
Player 1 enters a word
Hello
Enter a letter between A-Z
PS C:\Users\arora\Desktop\Programs\C>
问题原因及修复方案
1. scanf传参错误
scanf("%c", ans)未传递变量地址,会触发未定义行为导致程序崩溃,需改为scanf("%c", &ans)。
2. 输入缓冲区残留换行符
读取单词的scanf("%s", w)会在缓冲区留下换行符,后续scanf("%c", &ans)会直接读取该换行符,跳过用户输入。解决方法:在scanf前加空格忽略空白字符,即scanf(" %c", &ans)。
3. toupper函数未赋值返回值
toupper(w[i])和toupper(ans)仅计算大写值但未赋值回原变量,导致大小写匹配失效。需修改为:
w[i] = toupper(w[i]); ans = toupper(ans);
同时需包含头文件#include <ctype.h>,否则toupper无法正常工作。
4. 数组arr长度不足
char arr[len - 1];长度比单词短1,会导致越界访问。应改为char arr[len];,初始化循环也需遍历到len:
for (int i = 0; i < len; i++) { arr[i] = '_'; printf("%c", arr[i]); }
5. 胜利判断逻辑遗漏最后一个字符
胜利判断循环仅检查到len-1,最后一个字符未被验证,导致无法正确触发胜利条件。修改循环为:
for (int i = 0; i < len; i++) { if (arr[i] == '_') { flag = 1; break; } else { flag = 0; } }
修复后的完整代码
#include <stdio.h> #include <string.h> #include <ctype.h> int main() { char menu; int c = 0, flag = 0, life = 8; printf("\nWelcome to Hangman!!!"); printf("\nThis is a game of hangman."); printf(" Player 1 enters a random word and the other has to guess it."); printf(" You get 8 lives in total i.e. you can have a maximum of 8 wrong guesses."); printf("\n"); printf("Press n for new game\n"); printf("Press q to quit\n"); printf("\n"); scanf("%c", &menu); int i = 0, j = 0; char w[20]; if (menu == 'q') { printf("Exiting..."); printf(" Thanks for playing"); } else if (menu == 'n') { printf("Player 1 enters a word\n"); scanf("%s", w); int len = strlen(w); // 将单词转为大写 for (int i = 0; i < len; i++) { w[i] = toupper(w[i]); } printf("\e[1;1H\e[2J"); // 初始化与单词长度一致的下划线数组 char arr[len]; for (int i = 0; i < len; i++) { arr[i] = '_'; printf("%c ", arr[i]); } printf("\n"); while (life != 0) { flag = 0; // 检查是否还有未猜中的字符 for (int i = 0; i < len; i++) { if (arr[i] == '_') { flag = 1; break; } } if (!flag) { printf("\nYou Won!!\n"); printf("You Guessed The Word: %s\n", w); break; } else { char ans; printf("Enter a letter between A-Z: "); // 用空格忽略缓冲区的空白字符 scanf(" %c", &ans); ans = toupper(ans); c = 0; for (int j = 0; j < len; j++) { if (ans == w[j]) { arr[j] = ans; c++; } } if (c == 0) { life--; printf("Wrong guess!\n"); } // 打印当前猜测进度 printf("Current progress: "); for (int j = 0; j < len; j++) { printf("%c ", arr[j]); } printf("\nLives Remaining: %d\n", life); } } if (life == 0) { printf("\nYou Lost!!!\n"); printf("The Word Was: %s\n", w); } } else { printf("Invalid Character\n"); } return 0; }
内容的提问来源于stack exchange,提问作者AnimalPlayer258

