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

C语言游戏scanf跳过输入求助:重复游玩选择无响应

猜数字游戏scanf跳过输入问题解决

问题描述

我为编程课程制作了一款猜数字游戏,规则如下:选择下注的credits数量,猜测0至20之间的数字,若所选数字与随机生成的数字一致则赢得下注额,否则扣除下注的credits。但游戏结束后询问是否再次游玩时,scanf会跳过输入环节,直接判定为‘否’,打印用于判断的变量时无内容输出。

问题代码

#include <stdio.h>
#include <stdlib.h>

//your credits
int krediit = 100;
// your bet
int pakkumine;

int main(void) {
  //these are the rules
  //choose the amount of credit you want to bet. Choose a number between 0 and 20. If your number is equal to the randomly generated number you will win and gain the amount of money you had bet. If your number is not equal to the randomly generated number you will lose and your bet will be divorced from the amount of credits you have.
  printf("1) Vali krediidi kogus, mida soovid panustada\n2) Paku number vahemikus 0 kuni 20.\n3) Kui sinu pakutud number langeb kokku arvuti poolt valitud numbriga, siis võidad!\n\n\n\n\n");

  //asks you if you want to play
  char a;
  printf("Kas te tahate mängida? (j/e) ");
  scanf("%c", &a);
  //runs the game
  if (a == 'j'){
    mang();
  }
  else {
    //if you dont want to play
    printf("Käi perse, sa oled nõme.");
  }
  
  return 0;
}
//the game
int mang(){
  //how much credits are you betting
  int krediidipakkumine;
  printf("Kui palju krediiti te sooviksite panustada\n ");
  scanf("%d", &krediidipakkumine);
  //if your bet is a negative number, it wont let you play
  while (krediidipakkumine < 0){
    printf("Tapa ennast ära\n");
    scanf("%d", &krediidipakkumine);
  }
  //generates the number you had to guess
  int arvutiarv = rand() % 21;
  printf("Pakkuge arv 0 ja 20 vahel\n ");
  scanf("%d", &pakkumine);
  
  
  //cheks if you won or not and gives or takes credits from you
  if (pakkumine == arvutiarv){
    printf("Teie valisite %d ja arvuti valis %d  ", pakkumine, arvutiarv);
    krediit = krediit + krediidipakkumine;
    printf("palju õnne, te võitsite. Teil on nüüd %d krediiti\n ", krediit);
  }
  else {
    printf("Teie valisite %d ja arvuti valis %d  ", pakkumine, arvutiarv);
    krediit = krediit - krediidipakkumine;
    printf("Väga kahju, te kaotasite L + ratio. Teil on nüüd %d krediiti\n\n ", krediit);
  }

  //cheks if you want to play again (doesn't work)
  char b;
  printf("Kas tahate uuesti mängida? (j/e)\n ");
  scanf("%c", &b);
  printf("%c\n", b);
  if (b == 'j'){
    mang();
  }
  else {
    printf("Käi perse, sa oled nõme.");
  }
}

问题原因

核心问题是输入缓冲区的换行符残留:

  • 用scanf("%d", ...)读取数字时,输入完数字后按下的回车(\n)会留在输入缓冲区中。
  • 后续执行scanf("%c", &b)时,该函数会直接读取缓冲区中残留的换行符,而非等待用户输入的j或e,导致变量b的值为换行符,不满足b == 'j'的条件,直接进入else分支。

解决方法

有两种简单的修复方式:

方式1:读取字符前清空缓冲区

在读取b之前,调用getchar()吃掉残留的换行符:

//cheks if you want to play again (fixed)
char b;
printf("Kas tahate uuesti mängida? (j/e)\n ");
// 清空缓冲区的换行符
getchar();
scanf("%c", &b);
printf("%c\n", b);
if (b == 'j'){
  mang();
}
else {
  printf("Käi perse, sa oled nõme.");
}

方式2:在字符格式串前添加空格

空格会自动跳过所有空白字符(包括换行、空格、制表符),修改scanf的格式串为" %c":

//cheks if you want to play again (fixed)
char b;
printf("Kas tahate uuesti mängida? (j/e)\n ");
// 用空格跳过空白字符
scanf(" %c", &b);
printf("%c\n", b);
if (b == 'j'){
  mang();
}
else {
  printf("Käi perse, sa oled nõme.");
}

额外优化:初始化随机数种子

当前代码中rand()生成的随机数每次运行都是固定的,建议在main函数开头添加:

#include <time.h> // 需要引入time头文件

int main(void) {
  srand(time(NULL)); // 初始化随机数种子
  // 后续代码...
}

这样每次运行游戏,随机数都会不同。

来源标注

内容的提问来源于stack exchange,提问作者Robin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 19:25:44