这两天需要写一段sample code,给客户demo产品功能,程序需要跟用户交互,使用用户从键盘输入
的内容,根据输入的小时 & 分钟值去设定产品进入待机的时长。代码如下:- 001 int main(init argc, char *argv[])
-
002 {
-
003 printf("please input the time that system change to suspend\n");
-
004 printf("hour(0~23):\n");
-
005 scanf("%d", &timeout.hour);
-
006 while ((timeout.hour < 0) || (timeout.hour >= 24))
-
007 {
- 008 printf("the hour value is illegal, please input again:\n");
-
009 printf("hour(0~23):\n");
-
010 scanf("%d", &timeout.hour);
-
011 }
-
012
-
013 printf("minute(0~59):\n");
-
014 scanf("%d", &timeout.min);
-
015 while ((timeout.min < 1) || (timeout.min >= 60))
-
016 {
-
017 printf("the minute value is illegal, please input again:\n");
-
018 printf("minute(0~59):\n");
-
019 scanf("%d", &timeout.min);
-
020 }
-
021 printf("timeout value is %ds\n", (timeout.hour * 60 * 60 + timeout.min * 60));
-
022
-
023 ...
-
024 ...
-
025 ...
-
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()
的返回值即可解决。
- scanf("%d", &timeout.hour);
-
while (getchar() != '\n')
-
{
-
; //loop
-
}
修改后的代码如下:
- int main(int argc, char *argv[])
-
{
- int ret;
-
- printf("please input the time that system change to suspend\n");
- printf("hour(0~23):\n");
- ret = scanf("%d", &timeout.hour);
-
while (getchar() != '\n') /* clear the input buffer */
-
{
-
;//loop
-
}
-
while ((timeout.hour < 0) || (timeout.hour >= 24) || (0 == ret))
-
{
- printf("the hour value is illegal, please input again:\n");
- printf("hour(0~23):\n");
- ret = scanf("%d", &timeout.hour);
-
while (getchar() != '\n') /* clear the input buffer */
-
{
-
;//loop
-
}
-
}
- printf("minute(0~59):\n");
- ret = scanf("%d", &timeout.min);
-
while (getchar() != '\n') /* clear the input buffer */
-
{
-
;//loop
-
}
-
while ((timeout.min < 1) || (timeout.min >= 60) || (0 == ret))
-
{
- printf("the minute value is illegal, please input again:\n");
- printf("minute(0~59):\n");
- ret = scanf("%d", &timeout.min);
-
while (getchar() != '\n') /* clear the input buffer */
-
{
-
;//loop
-
}
-
}
- printf("timeout value is %ds\n", (timeout.hour * 60 * 60 + timeout.min * 60));
-
...
-
...
-
...
- }
被这个问题困扰了半天,主要原因还是对scanf()的实现机制了解的不够清楚。
阅读(3919) | 评论(0) | 转发(3) |