Hello Word!

黑夜给了我黑色眼睛,我却用它去寻找光明

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

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

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

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

/*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时,执行一段代码,输入b时执行另一段,但是事与愿违。这是由于没有理解每次调用getchar(),都会向后读取缓冲区一格的内容。可做如下修改,

        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()本身并不能存储,若要比较某个位置的字符与特定字符的关系,则应及时赋值变量,储存响应。

2018.5.15

阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_38967295/article/details/80317371
个人分类: 学问思辨
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

不良信息举报

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

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭