杂记之库函数scanf

参考自:http://blog.sina.com.cn/s/blog_5e8facd20100lqqg.html

 

scanf只能将缓冲区中的数字(使用了%d)读入iCmdNum,并清空缓冲区,而我们输入的是非数字,那么scanf读入失败,失败了它也就不会去清空缓冲区,这样造成的结果就是,我们不需要再输入其它字符,scanf每次都会去读缓冲区,每次都失败,每次都不会清空缓冲区,当下次再来读时发现缓冲区中有数据就不会停止等用户输入,接着又进入下一次的循环,死循环就形成了。

void CmdRunning()

{

    int iCmdNum;

    

    do {

                  printf("请选择:0. 退出;1. 新建文件;2. 打开文件;3.保存文件\n");

                  scanf("%d",& iCmdNum);

                  if (0 == iCmdNum) {

                         printf("谢谢使用,再见!\n");

                  }

                  else if (1 == iCmdNum) {

                         CreateFile();

                  }

                  else if (2 == iCmdNum) {

                         OpenFile();

                  }

                  else if (3 == iCmdNum) {

                         SaveFile();

                 }

                 else {

                         printf("对不起,你选择的数字不存在,请重新选择!\n");

                 }

        }while(iCmdNum!=0);

}


 

这段程序存在一个很严重的Bug,比如,运行程序后输入字’a’(非数字),回车,死循环出现了。

解决方法:

scanf("%d",&iCmdNum);”语句是V0.1版本出现死循环的关键,那么我们不妨先从这里入手。

其实只要将“%d“改为“%c”,即可解决死循环问题。比如:

    scanf("%c", &chCmd);               // chCmd是一个字符变量

    iCmdNum = atoi(&chCmd);                   //chCmd转换为整型数值

    为什么这样做就能够解决死循环问题呢?我们不妨编写不同的测试用例(在这里仅仅需要输入不同的数值即可)试试。

如果出现问题,将如何解释?

       提示

l        控制台中的所有输入都被认为是字符;

l        回车键是一个或两个字符(不同的操作系统和编译器有不同的解释,而在Windows控制台中回车键的ASCII码为10);

l        查看atoi的使用方法,注意它执行失败后的返回值。

    为什么将“%d“改为“%c”即可避免死循环?大家知道V0.1版本出现死循环的原因完全是因为scanf从缓冲区读取值失败

所引起的。因为在输入输出流中所有的类型都会被当作字符来看待,那么当使用%c来读入chCmd时,不管输入什么样的

值都会成功。当scanf成功之后,则会将缓冲区中的字符清空 (实际上是将“流指针”后移),等待下一次用户的输入,所

以它不会出现死循环。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值