C语言清空(刷新)缓冲区,从根本上消除那些奇怪的行为
缓冲区的优点很明显?它加快了程序的运行速度?减少了硬件的读写次数?让整个计算机变得流畅起来?但是?缓冲区也带来了一些负面影响?经过前面几节的学习相信读者也见识到了。
那么?该如何消除这些负面影响呢?思路其实也很简单?在输入输出之前清空?刷新?缓冲区即可?
对于输出操作?清空缓冲区会使得缓冲区中的所有数据立即显示到屏幕上?很明显?这些数据没有地方存放了?只能输出了。
对于输入操作?清空缓冲区就是丢弃残留字符?让程序直接等待用户输入?避免引发奇怪的行为。 本节的代码用到了一些暂时没有学到的知识?估计很多初学者会不理解?没关系?那就先记住吧?记不住就**吧?总之?按照葫芦画瓢就完了。 清空输出缓冲区
清空输出缓冲区很简单?使用下面的语句即可?
Windows 平台下的 printf()、puts()、putchar() 等输出函数都是不带缓冲区的=所以不用清空=下面的代码演示了如何在 Linux 和 Mac OS 平台下清空缓冲区=
程序运行后=第一个 pirntf() 立即输出=等待 5 秒以后=第二个 printf() 才输出=这就符合我们的惯性思维了。如果不加fflush(stdout)语句=程序运行后=第一个 printf() 并不会立即输出=而是等待 5 秒以后和第二个 scanf() 一起输出=已在《C语言数据输出大汇总以及轻量进阶》中进行了演示==这有点不符合我们的思维习惯。
清空输入缓冲区
首先=很遗憾地说=没有一种既简洁明了又适用于所有平台的清空输入缓冲区的方案。只有一种很蹩脚的方案能适用于所有平台=那就是将输入缓冲区中的数据都读取出来=但是却不使用。
大家不要以为我很轻松地就能说出这句话=我翻墙查阅了很多英文资料=又测试了很多平台和编译器才敢说的。
我们先说两种通用的方案=虽然它很蹩脚=但是却行之有效。
1) 使用 getchar() 清空缓冲区
getchar() 是带有缓冲区的=每次从缓冲区中读取一个字符=包括空格、制表符、换行符等空白符=只要我们让 getchar() 不停地读取=直到读完缓冲区中的所有字符=就能达到清空缓冲区的效果。请看下面的代码=
该代码不停地使用 getchar() 获取缓冲区中的字符=直到遇见换行符\n或者到达文件结尾才停止。由于大家所学知识不足=这段代码暂时无法理解=我也就不细说了=在实际开发中=大家按照下面的形式使用即可=
输入示例=
按下第一个回车键后=只有第一个 scanf() 读取成功了=第二个 scanf() 并没有开始读取=等我们再次输入并按下回车键后=第二个 scanf() 才开始读取=这就符合我们的操作习惯了。如果没有清空缓冲区的语句=按下第一个回车键后=两个 scanf() 都读取了=只是第二个 scanf() 读取失败了=让人觉得很怪异=这点已在《使用scanf从键盘输入数据》中进行了演示。
改变输入方式=再次尝试一下=
你看=第一次输入的多余内容并没有起作用=就是因为它们在第二个 scanf() 之前被清空了。
这种方案的关键之处在于=getchar() 是带有缓冲区的=并且一切字符通吃=或者说一切字符都会读取=不会忽略。不过这种方案有个缺点=就是要额外定义一个变量 c=对于有强迫症的读者来说可能有点难受。
2) 使用 scanf() 清空缓冲区
scanf() 还有一种高级用法=就是使用类似于正则表达式的通配符=这样它就可以读取所有的字符了=包括空格、换行符、制表符等空白符=不会再忽略它们了。并且=scanf() 还允许把读取到的数据直接丢弃=不用赋值给变量。
请看下面的语句=
第一个 scanf() 将逐个读取缓冲区中\n之前的其它字符=% 后面的 * 表示将读取的这些字符丢弃=遇到\n字符时便停止读取。由于所有从键盘的输入都是以回车结束的=而回车会产生一个\n字符=此时=缓冲区中尚有一个\n遗留=第二个 scanf() 再将这个\n读取并丢弃=这里的星号和第一个 scanf() 的星号作用相同。所以将\n连同它之前的字符全部读取并丢弃之后=也就相当于清除了输入缓冲区。
相信很多读者都不明白这种写法=没关系=下节我们在讲解 scanf() 的高级用法时还会再解释。
我们来演示这种方案的效果=
输入示例 ①=
输入示例 ②=
相比使用 getchar()=这种方案不用额外定义一个变量=看起来更加整洁。
转载:感谢您阅览,转载请注明文章出处“来源从小爱孤峰知识网:一个分享知识和生活随笔记录的知识小站”。
链接:C语言清空(刷新)缓冲区,从根本上消除那些奇怪的行为http://www.gufeng7.com/niaolang/453.html
联系:如果侵犯了你的权益请来信告知我们删除。邮箱:119882116@qq.com