A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

  1. /*
  2. *    剪刀石头布——>游戏规则
  3. *    *剪刀干掉布
  4. *    *石头干到剪刀
  5. *    *布干掉石头
  6. *    *剪刀平局剪刀
  7. *    *石头平局石头
  8. *    *布平局布
  9. *    思路:
  10. *        计算机随机出拳
  11. *        自己选择出拳
  12. *        判断输赢
  13. *        0.剪刀 1.石头  2.布
  14. *
  15. **   步骤:
  16. *        1、定义变量  保存计算机和我出的拳
  17. *        2、计算机 随机  出拳
  18. *        3、我出拳
  19. *        4、条件判断
  20. *        5、出结果
  21. */

  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. int computerNum=-1;
  25. int personNum=-1;
  26. /**
  27. *  定义一个函数验证人类出拳是否正确,不正确就重新输入:
  28. *   这里出现了一个问题就是:如果输入字符而不是数字就会陷入死循环
  29. *   请重新输入:输入有误,请重新输入:输入有误,请重新输入:输入有误,请重新输入:输入有误,请重新输入:输入有误,请重新输入:输入有误,请重新输入:输入有误,请重新输入:输入有误,请重新输入:输入有误,请重新输入:输入有误,请重新输入:输入有误,请重新输入:输入有误,请重新输入:输入有误,请重新输入:输入有误,请重新输入:输入有误,请重新输入:输入有误,请重新\350\276
  30. */
  31. void test(){
  32.     if(!(personNum==0||personNum==1||personNum==2)){
  33.     printf("输入有误,请重新输入:");
  34.     scanf("%d",&personNum);
  35.         test();
  36.     }
  37. }
  38. int main(int argc, const char * argv[]) {
  39.    
  40.     //计算机出拳
  41.     computerNum=arc4random_uniform(3);
  42.     printf("人类出拳(请输入0:剪刀、1:石头或者2:布,三选一):");
  43.     scanf("%d",&personNum);
  44.     test();
  45.     if (computerNum==0) {
  46.           if (personNum==0){
  47.             printf("平局");
  48.           }else if(personNum==1){
  49.             printf("人类胜出!");
  50.           }else if(personNum==2){
  51.             printf("计算机胜出!");
  52.           }
  53.     }else if (computerNum==1){
  54.         if (personNum==0){
  55.             printf("计算机胜出!");
  56.         }else if(personNum==1){
  57.             printf("平局");
  58.         }else if(personNum==2){
  59.             printf("人类胜出!");
  60.         }
  61.     }else if(computerNum==2){
  62.         if (personNum==0){
  63.             printf("人类胜出!");
  64.         }else if(personNum==1){
  65.             printf("计算机胜出!");
  66.         }else if(personNum==2){
  67.             printf("平局");
  68.         }

  69.     }
  70.    
  71.     return 0;
  72. }
复制代码


18 个回复

倒序浏览
scanf函数会有一个输入缓冲区,你定义的是一个int,但你输入的是一个字符型,scanf如果输入不匹配的话,是不会把那个字符取走的,所以下次scanf还会遇到那个字符。不知道对不对,我的理解是这样。
回复 使用道具 举报
王博Lynn 发表于 2015-8-18 13:43
scanf函数会有一个输入缓冲区,你定义的是一个int,但你输入的是一个字符型,scanf如果输入不匹配的话,是 ...

再补充一点,缓冲区的数值一直没有得到释放,scanf就会一直获取缓冲区的值,而不再通过屏幕获取用户输入的值,所以if里的条件一直会成立,下面语句块也会一直执行,并且执行时还是读取的缓冲区中你上一次输入的那个字符
回复 使用道具 举报
王博Lynn 发表于 2015-8-18 13:46
再补充一点,缓冲区的数值一直没有得到释放,scanf就会一直获取缓冲区的值,而不再通过屏幕获取用户输入的 ...

scanf原理:
整型和字符型混合输入会有问题
1)当用户输入内容后,用户输入的内容会被存放到scanf的输入缓冲区中,然后,scanf函数会根据格式控制字符串从输入缓冲区依次取它想要的内容。
2) 如果从缓冲区中取的内容和我们的格式要求一致,则把取的值存放到变量中。
3)如果格式不一致,则不修改变量的值。  注意空格也是字符
4)如果scanf缓冲区还有数据,scanf不会提示我们再次输入。

//你是说第四条吗
回复 使用道具 举报
DUKEMAN 发表于 2015-8-18 15:58
scanf原理:
整型和字符型混合输入会有问题
1)当用户输入内容后,用户输入的内容会被存放到scanf的输入 ...

差不多就是第四条的意思,我也不知道我说得对不对
回复 使用道具 举报
很明显第36行的错误   你在那调用test函数不是每次执行到那一行就返回去调用么,这叫自己搞自己  
回复 使用道具 举报
世界静极 发表于 2015-8-18 17:20
很明显第36行的错误   你在那调用test函数不是每次执行到那一行就返回去调用么,这叫自己搞自己   ...

可以自己调用自己的
回复 使用道具 举报
路过学习一下
回复 使用道具 举报
36  行  自己调用自己无限循环,所以会出现你说的那种情况!!!
回复 使用道具 举报
类型要一致

点评

我想说,玩家可能输入别的类型,怎么才能将这个bug去除  发表于 2015-8-19 00:18
回复 使用道具 举报
王博Lynn 发表于 2015-8-18 18:26
可以自己调用自己的

我只能说这个BUG是因为test无限循环了
回复 使用道具 举报
世界静极 发表于 2015-8-22 16:46
我只能说这个BUG是因为test无限循环了

无限循环的原因还不是因为一直读取的是缓冲区的内容
回复 使用道具 举报
王博Lynn 发表于 2015-8-22 21:20
无限循环的原因还不是因为一直读取的是缓冲区的内容

嗯嗯 缓冲区没学扎实
回复 使用道具 举报
世界静极 发表于 2015-8-22 16:46
我只能说这个BUG是因为test无限循环了

这是一个递归函数,我知道自己调用自己,只是因为对于缓冲区的了解不透彻,所以造成了无限循环

现在明白了点
回复 使用道具 举报
世界静极 发表于 2015-8-18 17:20
很明显第36行的错误   你在那调用test函数不是每次执行到那一行就返回去调用么,这叫自己搞自己   ...

如果只是输入自然数,36行就不存在问题的  ,输入字符才会出错
回复 使用道具 举报
那怎么样去除这个bug呢?用调用来实现的话
如果用for嵌套可以摆脱这个问题
回复 使用道具 举报
很好,遇到各种大神!
回复 使用道具 举报
看起来很复杂的样子哦 加油 好好学习 天天向上
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马