C语言骰子程序输入'y'无法继续运行问题求助
问题分析与解决
问题描述
首次在代码中使用switch case语句编写简易掷骰子程序,掷骰子功能正常,但询问是否重掷(y/n)时,输入'y'程序直接退出。附代码如下:
#include <stdio.h> #include <time.h> #include <stdlib.h> #define WON 0 #define LOSE 1 int rollDice(); int playGame(); int rollAgain(); int rollDice() { return rand() % 6+ 1; } int playGame() { srand(time(NULL)); int dice_1 = 0; int dice_2 = 0; int sum = 0; int result; printf("--------------\n"); printf("- HOW TO WIN -\n"); printf("--------------\n"); printf("Your dice roll must equal 7 or 11 or else you lose.\n"); printf("\n"); printf("Want to test your luck? "); printf("Press ENTER to roll the die\n"); fgetc(stdin); dice_1 = rollDice(); dice_2 = rollDice(); sum = dice_1 + dice_2; printf("Dice 1:%2d\nDice 2:%2d\nSum:%2d\n", dice_1, dice_2, sum); switch ( sum ) { case 7: case 11: result = WON; break; case 2: case 3: case 4: case 5: case 6: case 8: case 9: case 10: case 12: result = LOSE; break; } return result; } int rollAgain() { srand(time(NULL)); int dice_1 = 0; int dice_2 = 0; int sum = 0; int result; printf("Press ENTER to roll the die\n"); fgetc(stdin); dice_1 = rollDice(); dice_2 = rollDice(); sum = dice_1 + dice_2; printf("Dice 1:%2d\nDice 2:%2d\nSum:%2d\n", dice_1, dice_2, sum); switch ( sum ) { case 7: case 11: result = WON; break; case 2: case 3: case 4: case 5: case 6: case 8: case 9: case 10: case 12: result = LOSE; break; } } int main() { char answer; int result = playGame(); switch ( result ) { case WON: printf("You won the game.\n"); printf("Do you wish to play again? (y/n)"); scanf("%c", &answer); if(answer == 'y' || answer == 'Y'); { int rollAgain(); } break; case LOSE: printf("You lost the game.\n"); printf("Do you wish to play again?"); scanf("%c", &answer); if(answer == 'y' || answer == 'Y'); { int rollAgain(); } break; } return 0; }
需解决三个问题:
- 如何实现重掷功能?
- if语句为何失效?
- 是否是使用scanf而非fgets这类函数导致的问题?
问题解答
1. if语句失效的原因
你的代码里if语句末尾多了分号,这是致命语法错误:
if(answer == 'y' || answer == 'Y'); // 分号让if变成空语句,后续块和if无关 { int rollAgain(); // 这是函数声明,不是函数调用 }
- 分号代表if的逻辑体结束,后面的大括号块会被当作独立代码块执行,完全不受if条件控制。
- 块内的
int rollAgain();是声明函数,不是调用函数,正确调用写法是rollAgain();。
2. scanf引发的输入缓冲区问题
确实和scanf有关,但核心是输入缓冲区残留的换行符导致读取异常:
- 在
playGame()中,fgetc(stdin)会读取用户按下的回车(\n),但后续执行scanf("%c", &answer)时,缓冲区可能残留之前的换行符,导致scanf直接读取到\n而非用户输入的'y',进一步导致程序逻辑不符合预期。
3. 实现完整重掷功能的方案
要实现重复游戏,需要结合循环结构,同时修正代码中的其他错误,具体修改步骤如下:
步骤1:修正随机数种子的调用
srand(time(NULL))只需在程序启动时调用一次,重复调用会因时间间隔过短导致rand生成重复随机数,将其移至main函数开头。
步骤2:合并冗余代码
playGame和rollAgain逻辑完全重复,可合并为一个gameRound函数,减少代码冗余。
步骤3:修复循环与输入处理
- 用
do-while循环实现重复游戏逻辑; - 清除输入缓冲区的残留换行符,避免scanf读取异常;
- 修正if语句的语法错误,正确调用游戏函数。
修正后的完整代码
#include <stdio.h> #include <time.h> #include <stdlib.h> #define WON 0 #define LOSE 1 int rollDice(); int gameRound(); int rollDice() { return rand() % 6 + 1; } // 单次游戏逻辑,合并原playGame和rollAgain的功能 int gameRound() { int dice_1 = 0; int dice_2 = 0; int sum = 0; int result; printf("\nPress ENTER to roll the die\n"); // 清空输入缓冲区的残留换行符 while (getchar() != '\n'); fgetc(stdin); // 等待用户按回车 dice_1 = rollDice(); dice_2 = rollDice(); sum = dice_1 + dice_2; printf("Dice 1:%2d\nDice 2:%2d\nSum:%2d\n", dice_1, dice_2, sum); switch (sum) { case 7: case 11: result = WON; break; default: // 用default替代所有lose场景,简化代码 result = LOSE; break; } return result; } int main() { char answer; int result; // 仅初始化一次随机数种子 srand(time(NULL)); printf("--------------\n"); printf("- HOW TO WIN -\n"); printf("--------------\n"); printf("Your dice roll must equal 7 or 11 or else you lose.\n"); do { result = gameRound(); if (result == WON) { printf("You won the game.\n"); } else { printf("You lost the game.\n"); } printf("Do you wish to play again? (y/n) "); // 清空缓冲区残留换行符,确保读取到正确输入 while (getchar() != '\n'); scanf("%c", &answer); } while (answer == 'y' || answer == 'Y'); // 用户输入y/Y则继续游戏 return 0; }
关键修改说明
do-while循环保证游戏至少执行一次,且用户输入'y'时重复游戏;- 合并冗余函数,提升代码可维护性;
while (getchar() != '\n')清空输入缓冲区,避免残留换行符干扰后续输入读取;- 移除if语句后的分号,正确执行条件逻辑;
- switch用
default简化lose场景的代码。
内容的提问来源于stack exchange,提问作者Amburkins
相关产品推荐
相关产品推荐

