• getchar fflush 的分析笔记


    问题描述:

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

    示例代码:

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

    运行截图:

    image

    image

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

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

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

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

    image

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

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

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

    image

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

    image

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

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

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

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

    image

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

    image

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

    #include<stdio.h>
    
    
    int main()
    {
        int count=0,ch;
        printf("
    Please input a line char: ");
        fflush(stdout);  //
        fflush(stdin);   //
        
        do
        {
             fflush(stdin);
             ch = getchar();
             putchar(ch); 
             putchar('
    ');
             fflush(stdout);
             count++;
        }while((ch!='
    ')&&(ch!=' '));
    
        count--;
        printf("
    valid char is %d 
    ",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

  • 相关阅读:
    【mysql】mac上基于tar.gz包安装mysql服务
    【maven】在idea上创建maven多模块项目
    关于Class.getResource和ClassLoader.getResource的路径问题
    【maven】Maven打包后为何文件大小改变了
    git常用命令
    第一章 第一个spring boot程序
    第二章 eclipse中m2e插件问题
    第一章 mac下开发环境的配置
    第一章 开发中遇到的错误列表
    第十一章 企业项目开发--消息队列activemq
  • 原文地址:https://www.cnblogs.com/hythink/p/6143113.html
Copyright © 2020-2023  润新知