问题描述:

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

示例代码:

  1. #include<stdio.h>
  2. void main()
  3. {
  4. int count=,ch;
  5. printf("\nPlease input a line char: ");
  6. fflush(stdout);
  7. while((ch=getchar())!='\n')
  8. {
  9. if(ch==' ')
  10. break;
  11. count++;
  12. }
  13. printf("\n valid char is %d \n",count);
  14. }

运行截图:

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

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

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

  1. #include<stdio.h>
  2. void main()
  3. {
  4. int count=,ch;
  5. printf("\nPlease input a line char: ");
  6. fflush(stdout);
  7.  
  8. while((ch=getchar())!='\n')
  9. {
  10. putchar(ch);
  11. putchar('\n');
  12. fflush(stdout);
  13. if(ch==' ')
  14. break;
  15. count++;
  16. }
  17. printf("\nvalid char is %d \n",count);
  18. }

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

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

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

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

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

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

  • fflush(stdin)      清除掉 标准输入的缓冲 -- 本次实验对应 键盘
  • fflush(stdout)    清除掉 标准输出的缓冲 -- 本次实验对应 终端
  1. #include<stdio.h>
  2. void main()
  3. {
  4. int count=,ch;
  5. printf("\nPlease input a line char: ");
  6. fflush(stdout); //
  7. fflush(stdin); //
  8.  
  9. while((ch=getchar())!='\n')
  10. {
  11. putchar(ch); //
  12. putchar('\n'); //
  13. fflush(stdout);
  14. if(ch==' ')
  15. break;
  16. count++;
  17. fflush(stdin); //
  18. }
  19. printf("\nvalid char is %d \n",count);
  20. }

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

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

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

  1. #include<stdio.h>
  2.  
  3. int main()
  4. {
  5. int count=,ch;
  6. printf("\nPlease input a line char: ");
  7. fflush(stdout); //
  8. fflush(stdin); //
  9.  
  10. do
  11. {
  12. fflush(stdin);
  13. ch = getchar();
  14. putchar(ch);
  15. putchar('\n');
  16. fflush(stdout);
  17. count++;
  18. }while((ch!='\n')&&(ch!=' '));
  19.  
  20. count--;
  21. printf("\nvalid char is %d \n",count);
  22.  
  23. return ;
  24. }

         

WIN运行环境:

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

  1. [root@localhost exp_getch]# uname -a
  2. Linux localhost.localdomain 3.11.-.fc20.i686+PAE # SMP Thu Dec :: UTC i686 i686 i386 GNU/Linux

参考:

c primer plus 5th

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

getchar fflush 的分析笔记的更多相关文章

  1. 3.View绘制分析笔记之onLayout

    上一篇文章我们了解了View的onMeasure,那么今天我们继续来学习Android View绘制三部曲的第二步,onLayout,布局. ViewRootImpl#performLayout pr ...

  2. 4.View绘制分析笔记之onDraw

    上一篇文章我们了解了View的onLayout,那么今天我们来学习Android View绘制三部曲的最后一步,onDraw,绘制. ViewRootImpl#performDraw private ...

  3. 2.View绘制分析笔记之onMeasure

    今天主要学习记录一下Android View绘制三部曲的第一步,onMeasure,测量. 起源 在Activity中,所有的View都是DecorView的子View,然后DecorView又是被V ...

  4. 1.Android 视图及View绘制分析笔记之setContentView

    自从1983年第一台图形用户界面的个人电脑问世以来,几乎所有的PC操作系统都支持可视化操作,Android也不例外.对于所有Android Developer来说,我们接触最多的控件就是View.通常 ...

  5. zeromq源码分析笔记之线程间收发命令(2)

    在zeromq源码分析笔记之架构说到了zmq的整体架构,可以看到线程间通信包括两类,一类是用于收发命令,告知对象该调用什么方法去做什么事情,命令的结构由command_t结构体确定:另一类是socke ...

  6. glusterfs 4.0.1 api 分析笔记1

    一般来说,我们写个客户端程序大概的样子是这样的: /* glfs_example.c */ // gcc -o glfs_example glfs_example.c -L /usr/lib64/ - ...

  7. SEH分析笔记(X64篇)

    SEH分析笔记(X64篇) v1.0.0 boxcounter 历史: v1.0.0, 2011-11-4:最初版本. [不介意转载,但请注明出处 www.boxcounter.com  附件里有本文 ...

  8. 【转载】Instagram架构分析笔记

    原文地址:http://chengxu.org/p/401.html Instagram 架构分析笔记 全部 技术博客 Instagram团队上个月才迎来第 7 名员工,是的,7个人的团队.作为 iP ...

  9. CentOS下使用Iptraf进行网络流量的分析笔记

    CentOS下使用Iptraf进行网络流量的分析笔记 一.概述 Iptraf是一款linux环境下,监控网络流量的一款绝佳的免费小软件. 本博客其他随笔参考: Centos安装流量监控工具iftop笔 ...

随机推荐

  1. [笔记]ubuntu安装flashplayer

    为firefox安装: 下载tar.gz压缩包:http://get.adobe.com/cn/flashplayer/ 解压:tar -xvxf install_flash_player_11_li ...

  2. 在虚拟机中安装CentOS

    1.准备工具 我当时下载的是VMware9.0.2,之后升级即可. 2.安装VMware9.0.2,按照步骤安装即可,安装成功并运行 选择创建新的虚拟机,出现下图,选择"自定义"后 ...

  3. 关于docker在windows环境下运行的第一次体验

    关于docker在windows环境下执行的原理 1.1.           首先是Docker Quickstart启动,如果在虚拟机Oracle VM VirtualBox不存在default虚 ...

  4. 图像抠图算法学习 - Shared Sampling for Real-Time Alpha Matting

    一.序言   陆陆续续的如果累计起来,我估计至少有二十来位左右的朋友加我QQ,向我咨询有关抠图方面的算法,可惜的是,我对这方面之前一直是没有研究过的.除了利用和Photoshop中的魔棒一样的技术或者 ...

  5. 详解用CSS3制作圆形滚动进度条动画效果

    主  题 今天手把手教大家用CSS3制作圆形滚动进度条动画,想不会都难!那么,到底是什么东东呢?先不急,之前我分享了一个css实现进度条效果的博客<CSS实现进度条和订单进度条>,但是呢, ...

  6. phoneGap+cordova+ionic混合app开发环境搭建

    参考链接:http://www.w2  bc.com/article/177257 待补充

  7. CPU中断和轮询

    轮询顾名思义,CPU不停的询问,CPU很忙. 中断和轮询不同,是硬件上的,就像一个开关被按下了,没有什么东西在不停的询问开关有没有被按下,开关只是被按下了,就通电了,通电了就会发声一些事情. 可以看看 ...

  8. python 第一章学习课程

    http://www.runoob.com/python/python-dictionary.html

  9. [LeetCode] Evaluate Division 求除法表达式的值

    Equations are given in the format A / B = k, where A and B are variables represented as strings, and ...

  10. [LeetCode] Palindrome Number 验证回文数字

    Determine whether an integer is a palindrome. Do this without extra space. click to show spoilers. S ...