scanf和getchar使用问题

/*
 *作者: rookie_wei
 *
 *
 *说明:下面讨论一下在c语言中使用scanf和getchar从键盘中获取字符串出现的问题,
 *      这些问题很隐蔽,有时很难发现。希望能帮到你们。如果有什么理解错误之处,还请高手们指出。
 *
 *日期:2012.7.29
 */








例如代码:

int main(void)
{
    int a, b, c, max;
    char ch;
    do
    {
        printf("Please input a, b and c: \n");
        scanf("%d%d%d", &a, &b, &c);


        max = a > b ? a : b;
        max = max > c ? max : c;


        printf("Max = %d\n", max);


        printf("Y/y continue\n");
      
        ch = getchar();
        while((getchar()) != '\n');
        putchar(ch);
  
    }while(ch == 'y' || ch == 'Y');
   
    return 0;
}


运行结果:
rookiewei@ubuntu:~/classwork/c_test/sz_c_class/chapter5$ ./1
Please input a, b and c: 
1 2 3
Max = 3
Y/y continue
y


rookiewei@ubuntu:~/classwork/c_test/sz_c_class/chapter5$ 






其运行结果是即使最后输入键盘的是y/Y但是仍然不能进入循环。
分析问题的原因:
scanf的工作过程是将按键值存入输入缓冲区,然后直接读取输入缓冲区的内容,scanf遇到回车(\n)才结束
在上面的例子中,我们在键盘上输入的实际值是:
a\0b\0c\n   注:\0表示空格  \n表示回车

所以存在输入缓冲区的值是:a\0b\0c\n
scanf遇到回车(\n)而结束,scanf读取后输入缓冲区残留的内容就只剩下\n了,
所以下面的ch = getchar();语句在没有等到键盘输入时就已经读取了缓冲区的残留\n了,
因此即使键盘输入的是y/Y,但是ch获取的还是\n,这就解释了为什么当我们调用查看ch内容的
语句putchar(ch);时,结果输出的是换行而不是y。
由此可以猜测,scanf和getchar函数共用同一个输入缓冲区。

要解决此类问题的方法是,调用scanf函数后,将缓冲区里的残留清除掉,
做法是在scanf调用后使用while((getchar()) != '\n');语句清除残留。
将上面的代码改成
int main(void)
{
    int a, b, c, max;
    char ch;
    do
    {
        printf("Please input a, b and c: \n");
        scanf("%d%d%d", &a, &b, &c);
 while((getchar()) != '\n');
        
        max = a > b ? a : b;
        max = max > c ? max : c;


        printf("Max = %d\n", max);


        printf("Y/y continue\n");
        
        ch = getchar();
        while((getchar()) != '\n');
        putchar(ch);
    
    }while(ch == 'y' || ch == 'Y');
   
    return 0;
}


其输出结果是:
rookiewei@ubuntu:~/classwork/c_test/sz_c_class/chapter5$ ./1         
Please input a, b and c: 
1 2 3
Max = 3
Y/y continue
y
yPlease input a, b and c: 


正是想要的结果。
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值