目录
具体代码如下( 仅供参考 )
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void menu()
{
printf("\n");
printf(" 1->play \n");
printf(" 0->exit \n");
printf("\n");
}
// rand函数在使用前 要先使用srand函数来设置随机数的生成器
// 否则每次运行会生成相同的序列。
void game(void)
{
int num = rand() % 100 + 1;
// rand生成的是伪随机数: 就是每一次重新运行是随机数的顺序是确定的
// 比如第一次是生成的前三个是42 99 5 那重新启动时 前三个随机数依然时42 99 5达不到目的
do {
int input1;
if (scanf("%d", &input1) != 1)
{
printf("输入格式错误,请输入数字\n");
// 清理输入缓冲区
while (getchar() != '\n');
continue;
}
if (input1 > num)
{
printf("猜大了 请重新输入->\n");
}
else if (input1 < num)
{
printf("猜小了 请重新输入->\n");
} else
{
printf("恭喜你 猜对了正确答案是:%d\n\n\n", num);
break;
}
} while (1);
}
int main()
{
int input;
srand((unsigned int)time(NULL));
// 在C语言中,srand() 函数用于初始化随机数生成器的种子
// 只调用一次就够了 不然不够随机 连续快速输入两次可能会相同
do
{
menu();
printf("请选择;\n");
if (scanf("%d", &input) != 1)
{
printf("输入格式错误,请输入数字\n");
// 清理输入缓冲区
while (getchar() != '\n');
continue;
}
switch (input)
{
case 1:
printf("游戏开始\n");
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("输入错误 请重新选择\n");
break;
}
} while (input);
return 0;
}
背景:
在 C 语言里,scanf
函数是用于从标准输入(通常是键盘)读取格式化数据的。
当使用 scanf("%d", &input)
时,它期望用户输入一个整数。要是用户输入的是字母或者其他非数字字符,scanf
就无法把输入转换为整数,读取操作就会失败,并且这个非数字字符会留在输入缓冲区里。
若不清理输入缓冲区,后续的 scanf
调用会直接读取到这个留在缓冲区里的非数字字符,从而导致持续的读取失败,让程序陷入一种不符合预期的状态。(既导致进入无限循环)
报错原因:
当输入字母时,scanf
函数会因为格式不匹配而失败,并且会将字母留在输入缓冲区,从而导致后续的输入操作受到影响。为了让程序在输入字母时依旧可以返回循环,你需要清理输入缓冲区.
清理输入缓冲区的方法和原因:
方法:
while (getchar() != '\n');
getchar
函数的功能是从标准输入读取一个字符。这个循环会不断调用 getchar
函数,把输入缓冲区里的字符逐个读取出来,直到遇到换行符 '\n'
为止。换行符一般是用户按下回车键产生的,表示一次输入结束。
原因:
-
避免影响后续输入:当
scanf
读取失败时,非数字字符会留在输入缓冲区里。若不清理,后续的scanf
调用会直接读取到这个非数字字符,导致持续的读取失败。 -
确保程序正常运行:清理输入缓冲区可以让程序回到正常的输入等待状态,等待用户重新输入有效的数据。
补充:
清理输入缓冲区:
while (getchar() != '\n');
:这是用于清理输入缓冲区的代码。getchar
函数每次从输入缓冲区读取一个字符,这个循环会持续读取字符,直到遇到换行符'\n'
为止,这样就能把输入缓冲区里的所有字符都清空。错误处理:在
game
函数和main
函数中,当scanf
读取失败时,输出错误信息并清理输入缓冲区,然后继续循环。
continue;
:跳过本次循环的剩余部分,直接进入下一次循环,等待用户重新输入。通过清理输入缓冲区,就能保证程序在用户输入错误时也能稳定运行,持续等待用户输入正确的数据。