getchar fflush 的分析笔记
问题描述:
统计从键盘输入的若干个字符中有效字符的个数,以换行符作为输入结束。有效字符是指第一个空格符前面的字符,若输入字符中没有空格符,则有效字符为除了换行符之外的所有字符。
示例代码:
#include<stdio.h>
void main()
{
int count=,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);
}
运行截图:


由于空格而break 由于换行符而退出 while
疑问:getchar() 函数每次只能读入一个字符,但是为什么这里一次就实现了一行字符的输入和处理呢? 简单的说:这是由于缓冲机制而实现的,以下层层分析:
分析字符是如何取的:修改while看看每次循环的 ch
#include<stdio.h>
void main()
{
int count=,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);
}

可见:每次循环确实是依次取一个字符来处理的,最后取的是空格符,打印空格换行后由于碰到 判断而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) 清除掉 标准输出的缓冲 -- 本次实验对应 终端
 
#include<stdio.h>
void main()
{
int count=,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内打印出来的。

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

备忘:注意使用与逻辑while((ch!='\n')&&(ch!=' ')),之前由于逻辑错误用的或逻辑,导致程序死循环了:
#include<stdio.h> int main()
{
int count=,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 ;
}
          
WIN运行环境:

Linux运行环境:测试发现、Linux环境下 fflush() 似乎不管用,具体可见参考博客
[root@localhost exp_getch]# uname -a
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 的分析笔记的更多相关文章
- 3.View绘制分析笔记之onLayout
		
上一篇文章我们了解了View的onMeasure,那么今天我们继续来学习Android View绘制三部曲的第二步,onLayout,布局. ViewRootImpl#performLayout pr ...
 - 4.View绘制分析笔记之onDraw
		
上一篇文章我们了解了View的onLayout,那么今天我们来学习Android View绘制三部曲的最后一步,onDraw,绘制. ViewRootImpl#performDraw private ...
 - 2.View绘制分析笔记之onMeasure
		
今天主要学习记录一下Android View绘制三部曲的第一步,onMeasure,测量. 起源 在Activity中,所有的View都是DecorView的子View,然后DecorView又是被V ...
 - 1.Android 视图及View绘制分析笔记之setContentView
		
自从1983年第一台图形用户界面的个人电脑问世以来,几乎所有的PC操作系统都支持可视化操作,Android也不例外.对于所有Android Developer来说,我们接触最多的控件就是View.通常 ...
 - zeromq源码分析笔记之线程间收发命令(2)
		
在zeromq源码分析笔记之架构说到了zmq的整体架构,可以看到线程间通信包括两类,一类是用于收发命令,告知对象该调用什么方法去做什么事情,命令的结构由command_t结构体确定:另一类是socke ...
 - glusterfs 4.0.1 api  分析笔记1
		
一般来说,我们写个客户端程序大概的样子是这样的: /* glfs_example.c */ // gcc -o glfs_example glfs_example.c -L /usr/lib64/ - ...
 - SEH分析笔记(X64篇)
		
SEH分析笔记(X64篇) v1.0.0 boxcounter 历史: v1.0.0, 2011-11-4:最初版本. [不介意转载,但请注明出处 www.boxcounter.com 附件里有本文 ...
 - 【转载】Instagram架构分析笔记
		
原文地址:http://chengxu.org/p/401.html Instagram 架构分析笔记 全部 技术博客 Instagram团队上个月才迎来第 7 名员工,是的,7个人的团队.作为 iP ...
 - CentOS下使用Iptraf进行网络流量的分析笔记
		
CentOS下使用Iptraf进行网络流量的分析笔记 一.概述 Iptraf是一款linux环境下,监控网络流量的一款绝佳的免费小软件. 本博客其他随笔参考: Centos安装流量监控工具iftop笔 ...
 
随机推荐
- Apache主配置文件httpd.conf 详解
			
Apache的主配置文件:/etc/httpd/conf/httpd.conf 默认站点主目录:/var/www/html/ Apache服务器的配置信息全部存储在主配置文件/etc/httpd/co ...
 - Spring框架值注解
			
注解配置概括 Spring可以按指定的包路径扫描内部的组件,当发现组件类定义前有一下的注解标记,会将该组件纳入Spring容器中. 1)@Component(其他组件) 2)@Controller(A ...
 - js 页面刷新location.reload和location.replace的区别小结
			
reload 方法,该方法强迫浏览器刷新当前页面. 语法: location.reload([bForceGet]) 参数: bForceGet, 可选参数, 默认为 false,从客户端缓存里取当前 ...
 - [LeetCode] Permutations II 全排列之二
			
Given a collection of numbers that might contain duplicates, return all possible unique permutations ...
 - 20145215&20145307《信息安全系统设计基础》实验二 固件设计
			
20145215&20145307<信息安全系统设计基础>实验二 固件设计 实验目的与要求 了解多线程程序设计的基本原理,学习 pthread 库函数的使用. 了解在 linux ...
 - AppBox v6.0中实现子页面和父页面的复杂交互
			
前言 1. AppBox是捐赠开源(获取源代码至少需要捐赠作者 1 元钱),基于的 FineUI(开源版)则是完整开源,网址:http://fineui.codeplex.com/ 2. 你可以通过捐 ...
 - knockout学习笔记目录
			
关于knockout学习系列的文章已经写完,这里主要是做个总结,并且将目录罗列出来,方便查看.欢迎各位大神拍砖和讨论. 总结 kncokout是一个轻量级的UI类库,通过MVVM模式使前端的UI简单话 ...
 - 【机器学习Machine Learning】资料大全
			
昨天总结了深度学习的资料,今天把机器学习的资料也总结一下(友情提示:有些网站需要"科学上网"^_^) 推荐几本好书: 1.Pattern Recognition and Machi ...
 - .NET跨平台之旅:探秘 dotnet run 如何运行 .NET Core 应用程序
			
自从用 dotnet run 成功运行第一个 "Hello world" .NET Core 应用程序后,一直有个好奇心:dotnet run 究竟是如何运行一个 .NET Cor ...
 - Java的基本数据类型与转换
			
1.1 Java为什么需要保留基本数据类型 http://www.importnew.com/11915.html 基本数据类型对大多数业务相关或网络应用程序没有太大的用处,这些应用一般是采用客户端/ ...