Chinaunix首页 | 论坛 | 博客
  • 博客访问: 578972
  • 博文数量: 88
  • 博客积分: 4769
  • 博客等级: 中校
  • 技术积分: 989
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-24 02:31
文章分类

全部博文(88)

文章存档

2012年(4)

2011年(35)

2010年(49)

分类: C/C++

2011-07-09 00:11:15

这两天需要写一段sample code,给客户demo产品功能,程序需要跟用户交互,使用用户从键盘输入
的内容,根据输入的小时 & 分钟值去设定产品进入待机的时长。代码如下:
  1. 001 int main(init argc, char *argv[])
  2. 002 {
  3. 003     printf("please input the time that system change to suspend\n");
  4. 004     printf("hour(0~23):\n");
  5. 005     scanf("%d", &timeout.hour);
  6. 006     while ((timeout.hour < 0) || (timeout.hour >= 24))
  7. 007     {
  8. 008         printf("the hour value is illegal, please input again:\n");
  9. 009         printf("hour(0~23):\n");
  10. 010         scanf("%d", &timeout.hour);
  11. 011     }
  12. 012
  13. 013     printf("minute(0~59):\n");
  14. 014     scanf("%d", &timeout.min);
  15. 015     while ((timeout.min < 1) || (timeout.min >= 60))
  16. 016     {
  17. 017         printf("the minute value is illegal, please input again:\n");
  18. 018         printf("minute(0~59):\n");
  19. 019         scanf("%d", &timeout.min);
  20. 020      }
  21. 021     printf("timeout value is %ds\n", (timeout.hour * 60 * 60 + timeout.min * 60));
  22. 022
  23. 023     ...
  24. 024     ...
  25. 025     ...
  26. 026 }
    在使用这段代码读取用户的输入时,若输入值是我们期待的合法值,则程序可正常运行;但如果输入
内容为非法值时,则会出现异常,具体表现为:
第五行的代码:
    scanf("%d", &timeout.hour);
    期待输入一个0~23之间的数字,如果输入是字母、符号等非法值,则程序会直接跑到15行的第二个
while,并进入死循环,不断的重复打印17行和18行的输出内容。
    此外,14行和19行的scanf()也没有阻塞。

    经过分析,发现问题是出在scanf()这个函数中,第5行的scanf()在读取输入时,若发现是非法值,
scanf()会将读取到的内容放回输入缓冲区并返回0,程序继续往下执行;
    执行到14行的scanf()时,也会从缓冲区读取输入,执行过程同上,发现是非法值,所以就将读取的
内容放回输入缓冲区并返回0,继续往下执行;
    执行到19行的scanf()时也是同样的操作。
    这样就会导致程序一直在15~20行的代码段循环。

    解决办法,在scanf()读取输入后,将非法输入读出来,清空缓冲区,如下所示,再配合判断scanf()
的返回值即可解决。
  1. scanf("%d", &timeout.hour);
  2. while (getchar() != '\n')
  3. {
  4.     ; //loop
  5. }
修改后的代码如下:

  1. int main(int argc, char *argv[])
  2. {
  3.     int ret;

  4.     printf("please input the time that system change to suspend\n");
  5.     printf("hour(0~23):\n");
  6.     ret = scanf("%d", &timeout.hour);
  7.     while (getchar() != '\n') /* clear the input buffer */
  8.     {
  9.         ;//loop
  10.     }
  11.     while ((timeout.hour < 0) || (timeout.hour >= 24) || (0 == ret))
  12.     {
  13.         printf("the hour value is illegal, please input again:\n");
  14.         printf("hour(0~23):\n");
  15.         ret = scanf("%d", &timeout.hour);
  16.         while (getchar() != '\n') /* clear the input buffer */
  17.         {
  18.             ;//loop
  19.         }
  20.     }
  21.     printf("minute(0~59):\n");
  22.     ret = scanf("%d", &timeout.min);
  23.     while (getchar() != '\n') /* clear the input buffer */
  24.     {
  25.         ;//loop
  26.     }
  27.     while ((timeout.min < 1) || (timeout.min >= 60) || (0 == ret))
  28.     {
  29.         printf("the minute value is illegal, please input again:\n");
  30.         printf("minute(0~59):\n");
  31.         ret = scanf("%d", &timeout.min);
  32.         while (getchar() != '\n') /* clear the input buffer */
  33.         {
  34.             ;//loop
  35.         }
  36.     }
  37.     printf("timeout value is %ds\n", (timeout.hour * 60 * 60 + timeout.min * 60));
  38.     ...
  39.     ...
  40.     ...
  41. }

    被这个问题困扰了半天,主要原因还是对scanf()的实现机制了解的不够清楚。

阅读(3826) | 评论(0) | 转发(3) |
给主人留下些什么吧!~~