清除缓冲区的几种方法


一、缓冲区的作用

  • 一般缓冲区的作用是为了防止频繁的读写。
    • 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:使用这种方法,简单快捷,只需把这几行复制到需要的输入的代码之前,应对用户的各种诡异输入,都可以清除干净。同时它可以自动判断是否需要进行清除操作,避免了程序的意外停止。很好用!!!

scanf函数在读取数据时,并没有将输入缓冲区中的所有内容都读取完毕,导致部分数据仍然留在缓冲区内。这是因为scanf函数具有一个特性:当程序执行到scanf("%s", &password);这一行时,scanf会检查输入缓冲区是否为空,如果不为空,scanf将等待用户输入。因此,如果在使用多个scanf函数时,输入缓冲区中还有未读取的数据,scanf函数将直接使用缓冲区中的数据,而不会要求用户重新输入。 为了清除输入缓冲区,有以下几种有效的方法: 1. 使用getchar函数:通过连续调用getchar函数,将输入缓冲区中的字符一个一个地读取并丢弃,直到缓冲区中没有字符为止。例如: ```c int c; while ((c = getchar()) != '\n' && c != EOF); ``` 2. 使用fflush函数:调用fflush(stdin)可以清空输入缓冲区,但是根据C语言标准规定,fflush函数只能用于清空输出缓冲区,对于输入缓冲区清空并不是标准行为,因此在不同的编译器下可能会有不同的结果。 3. 使用fgets函数:fgets函数可以读取一行字符,可以通过读取缓冲区中的所有字符来清空输入缓冲区。例如: ```c char buffer<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [如何清空输入缓冲区](https://blog.csdn.net/m0_66769266/article/details/124151575)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [C语言清除scanf()缓存的案例讲解](https://download.csdn.net/download/weixin_38628552/13782303)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值