You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 21:45:38