While循环与getchar()组合巧妙清除缓存区内容

最近做题发现键入回车后,总会产生一些意料之外的结果……并未完全达到预期的目标,今日偶的解法,隧简单分析一波。


先从一个简单的小程序开始,我们先忽略它糟糕的算法:

/*guess.c--一个糟糕且错误的猜数字程序
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
   int i=1;
   printf("Think a number in your mind,I will guess it.\n");
   printf("Input a y if I'm right and an n if I am wrong\n");
   while (getchar() != 'y')//读取字符,与y做对比
   printf("The number is %d, right?\n", i++);
   system("pause");
   return 0;
}

我在心中默想一个数,通过键入 y y 或者n,告诉程序,它的猜测是否正确。我们可以注意到,每次输入 n n ,程序打印两条消息;直接输入回车,也会打印一条消息。这是因为程序将n当作我否定数字 1 1 ,将[Enter]当作我否定了数字 2 2
guess.c
要解决这个问题,我们要了解程序是如何使用用户输入的字符的。我们输入的字符被收集并储存在一个称为缓冲区的临时储存区,按下[Enter]后,程序才能使用我们输入的字符,直到缓冲区内的字符全都被读取完,如下图:
缓冲输入
这里我们只讨论缓冲输入,对于非缓冲输入不会遇到这样的问题,故不做赘述。知道了问题的关键,我们可以设计一个 whlie w h l i e 循环来丢弃输入行剩余的内容,包括换行符。

while (getchar() != 'y')
{
    printf("The number is %d, right?\n", i++);
    while (getchar() != '\n')
        continue;//跳过剩余输入行
}

这相当于把字符从缓存区取出后,执行一段空语句。 getchar() g e t c h a r ( ) 将一直读取,一直丢弃,直到清空缓存区。使用上述循环后,程序输出如下:
guess-1.c

这体现出,每使用一次 getchar() g e t c h a r ( ) 只能读取当前字符的后一个字符, getchar() g e t c h a r ( ) 本身并不能存储,若要比较某个位置的字符与特定字符的关系,则应及时赋值变量,储存响应。

/*guess-1.c--另一个糟糕且错误的猜数字程序
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
    int i = 50, upper = 100, lower = 0;
    printf("50?\n");
    while (getchar()!= 'y')                  //输入char-1 '\n'。其中char-1被取出,此时缓存区中:'\n'。
    {
        printf("Tell me big or small:\n");
        while (getchar() != '\n')            //此时缓存区被清空
            continue;
        if (getchar() == 'a')                //输入char-2 '\n'。其中char-2被取出与'a'进行比较,此时缓存区中:'\n'。
        {
            i = 1;
            printf("%d?", i);
            while (getchar() != '\n')
                continue;
        }
        if (getchar() == 'b')                //缓存区中的'\n'被取出与'b'进行比较。
        {
            i = 2;
            printf("%d?", i);
            while (getchar() != '\n')
                continue;
        }
     }
     system("pause");
     return 0;
}

我们想做到输入 a a 时,执行一段代码,输入b时执行另一段,但是事与愿违。这是由于没有理解每次调用 getchar() g e t c h a r ( ) ,都会向后读取缓冲区一格的内容。可做如下修改,

        char ch;
        ch=getchar();                //及时赋值变量以储存响应。
        if (ch == 'a')                
        {
            i = 1;
            printf("%d?", i);
            while (getchar() != '\n')
                continue;
        }
        if (ch == 'b')                
        {
            i = 2;
            printf("%d?", i);
            while (getchar() != '\n')
                continue;
        }

再次强调: getchar() g e t c h a r ( ) 本身并不能存储,若要比较某个位置的字符与特定字符的关系,则应及时赋值变量,储存响应。

2018.5.15

  • 11
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值