getchar fflush 的分析笔记

Posted .Think

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了getchar fflush 的分析笔记相关的知识,希望对你有一定的参考价值。

问题描述:

统计从键盘输入的若干个字符中有效字符的个数,以换行符作为输入结束。有效字符是指第一个空格符前面的字符,若输入字符中没有空格符,则有效字符为除了换行符之外的所有字符。

示例代码:

#include<stdio.h>
void main()
{
    int count=0,ch;
    printf("\\nPlease input a line char: ");
    fflush(stdout);
    while((ch=getchar())!=\'\\n\')
    {
        if(ch==\' \')
            break;
        count++;
    }
    printf("\\n valid char is %d \\n",count);
}

运行截图:

image

image

由于空格而break                                                        由于换行符而退出 while

疑问:getchar() 函数每次只能读入一个字符,但是为什么这里一次就实现了一行字符的输入和处理呢?    简单的说:这是由于缓冲机制而实现的,以下层层分析:

分析字符是如何取的:修改while看看每次循环的 ch

#include<stdio.h>
void main()
{
    int count=0,ch;
    printf("\\nPlease input a line char: ");
    fflush(stdout);
 
    while((ch=getchar())!=\'\\n\')
    {
        putchar(ch);
        putchar(\'\\n\');
        fflush(stdout);
        if(ch==\' \')
            break;
        count++;
    }
    printf("\\nvalid char is %d \\n",count);
}

image

可见:每次循环确实是依次取一个字符来处理的,最后取的是空格符,打印空格换行后由于碰到 判断而break。

疑问还是存在,运行程序时,明明只输入了一次getchar(),怎么导致一行的字符都输入处理了呢?

缓冲机制示意图:系统在接收输入字符时,首先将字符存在了一段缓冲区域中,直到遇到换行符停止接收。如图,换行符 ‘\\n’也会被存储在其中。

image

由于上述代码,在每次执行 getchar() 取字符时,并没有清掉缓冲区中的内容,所以,程序会一直从缓冲区中取字符数据。因此,while 循环依次取的字符为 ‘v’,’o’,’i’,’d’,’ ’,遇到空格后而break。

image

同样,在输入nospace时,也是依次从缓冲区中取字符。因此,while 循环依次取的字符为 ‘n’,’o’,’s’,’p’,’a ’,’c’,’e’,’\\n’,遇到换行’\\n’后而结束while循环。

如何利用fflush清除掉之前的缓冲?

  • fflush(stdin)      清除掉 标准输入的缓冲 -- 本次实验对应 键盘
  • fflush(stdout)    清除掉 标准输出的缓冲 -- 本次实验对应 终端
#include<stdio.h>
void main()
{
    int count=0,ch;
    printf("\\nPlease input a line char: ");
    fflush(stdout);  //
    fflush(stdin);   //
    
    while((ch=getchar())!=\'\\n\')
    {
        putchar(ch);        //
        putchar(\'\\n\');      //
        fflush(stdout);
        if(ch==\' \')
            break;
        count++;
        fflush(stdin);      //
    }
    printf("\\nvalid char is %d \\n",count);
}

增加清除缓冲后,输入void main的运行截图,可见程序只处理了第一个字符’v’,然后由于不满足结束条件,又正在执行getchar() 取字符,但此时缓冲区中的字符已经被count++后面的fflush(stdin)清理了,故程序在等待用户输入字符。注意:输入语句下一行的’v’和换行是在while内打印出来的。

image

下面继续输入’o’,’i’,’d’,’ ’,getchar每次取到后,while循环中会打印出来并换行,直到碰到空格而break:

image

 

备忘:注意使用与逻辑while((ch!=\'\\n\')&&(ch!=\' \')),之前由于逻辑错误用的或逻辑,导致程序死循环了:

#include<stdio.h>


int main()
{
    int count=0,ch;
    printf("\\nPlease input a line char: ");
    fflush(stdout);  //
    fflush(stdin);   //
    
    do
    {
         fflush(stdin);
         ch = getchar();
         putchar(ch); 
         putchar(\'\\n\');
         fflush(stdout);
         count++;
    }while((ch!=\'\\n\')&&(ch!=\' \'));

    count--;
    printf("\\nvalid char is %d \\n",count);

    return 0;
}

image          image

WIN运行环境:

image

Linux运行环境:测试发现、Linux环境下 fflush() 似乎不管用,具体可见参考博客

[root@localhost exp_getch]# uname -a
Linux localhost.localdomain 3.11.10-301.fc20.i686+PAE #1 SMP Thu Dec 5 14:12:06 UTC 2013 i686 i686 i386 GNU/Linux

参考:

c primer plus 5th 

http://blog.csdn.net/kang99827765/article/details/50593839

以上是关于getchar fflush 的分析笔记的主要内容,如果未能解决你的问题,请参考以下文章

解决linux下fflush(stdin)无效

解决linux下fflush(stdin)无效

scanf

leeson_020 分支语句 笔记

清理缓冲区

C语言知识点总结笔记吃透getchar()函数,超详细解析!!!