一、缓冲区的作用

* 一般缓冲区的作用是为了防止频繁的读写。

* A:往缓冲区里写,这里会有一个写的等待时间,并不总是有数据需要写;
* B: 从缓冲区里读,这里就有一个读间(没有数据或数据不全)的等待时间;
使用缓冲区可以减小程序输入时的等待,程序线程可以腾出CPU时间做其它的工作;

二、缓冲区的问题

缓冲区在提升了程序效率的同时,也带来了一些问题。

在项目的编写的工程中,很多时候并不需要用户的输入,这时如果用户输入,输入的信息就会被存入缓冲区中,当程序真的需要输入时,这些之前输入的信息,会被传入程序。造成程序获取错误信息,甚至是崩溃。

三、解决方案

1.使用fflush(stdin)

* 优点:使用这种方法清除缓冲区,简单快捷,只需将这条语句放入程序的输入语句的前面。
* 缺陷:但是这个方法有很大缺陷,因为在c语言得标准中没有明确规定这种用法,所以并不是所有的编译器都支持。

* 如果编译器支持,那么清除缓冲区就很简单了。
* 如果编译器不支持,它并不会报错,只是执行完这条语句后,缓冲区的内容依然存在。
2.getch()的连续获取
while(getchar()!='\n') continue;
* 优点:使用这种方法进行缓冲区的清除,通用性好,任何系统和编译器都支持。
* 缺陷:缓冲区清除的不彻底,这种缓冲区清除方法,依据判断获取字符为“换行符”来停止。

* 如果缓冲区中有换行符,但不是最后一个字符,这时缓冲区中第一个换行符之前(包括换行符)被清掉,但是第一个换行符的后面字符不会被清掉。
* 如果缓冲区中没有换行符,那么while会进入死循环,程序会停下来,这时只有按下回车键,程序才会向后运行,这样很影响用户体验。
* 在无法判断是否需要清除缓冲区时,无法使用这个方法,因为这会导致程序无故停顿等待用户输入回车键
3.setbuf()

* 原理:使stdin输入流由默认缓冲区转为无缓冲区。
* 优点:使用这种方法清除缓冲区,简单快捷,只需将这条语句放入程序的输入语句的前面。
* 缺陷:通用性不好,这种方法只适用于Windows的大部分编译器,linux和Windows的少量编译器使用时没有反应。
4.scanf(“%*[^\n]%*c”)

原理:%*
〔^\n〕将逐个读取缓冲区中的’\n’字符之前的其它字符,%后面的*表示将读取的这些字符丢弃,前遇到’\n’字符时便停止读取操作,此时,缓冲区中尚有一个’\n’字符遗留,所以后面的%*c将读取并丢弃这个遗留的换行符,这里的星号和前面的星号作用相同。由于所有从键盘的输入都是以回车结束的,而回车会产生一个’\n’字符,所以将’\n’连同它之前的字符全部读取并丢弃之后,也就相当于清除了输入缓冲区。

* 优点:使用这种方法进行缓冲区的清除,通用性好,任何系统和编译器都支持。
* 缺陷:缓冲区清除的不彻底,这种缓冲区清除方法,依据判断获取字符为“换行符”来停止。

* 在无法判断是否需要清除缓冲区时,无法使用这个方法,因为这会导致程序无故停顿等待用户输入回车键
5.判断键盘输入
while (_kbhit()) { getch(); }
kbhit()是一个C和C++函数,用于非阻塞地响应键盘输入事件。

这是一个我自己发现的一个清缓冲区方法:
* 使用kbhit()判断是否有键盘输入,即判断缓冲区内是否有内容。
* 如果缓冲区有内容,就使用getch()去获取,直到缓冲区内的所有输入都被清掉。

ps:使用这种方法,简单快捷,只需把这几行复制到需要的输入的代码之前,应对用户的各种诡异输入,都可以清除干净。同时它可以自动判断是否需要进行清除操作,避免了程序的意外停止。很好用!!!

技术
©2019-2020 Toolsou All rights reserved,
Mybatis映射文件Mapper.xml中#和$的区别SSM项目的excel文件上传并添加到数据库keras从dataframe中读取数据并进行数据增强进行训练(分类+分割)使用mt-range实现一个数字随着滑动杆变化的效果判断当前对象是不是数组的4种方式雷军:两年前和卢伟冰喝酒到凌晨三点 钦佩其工作热情和能力el-ui:select获取值airflow 定时任务+时间设定+cron表达式 云计算的最大安全风险:安全责任不清人工智能算法总结