c语言清空文件内容_C 语言清空输入缓冲区的几个手段

先观察如下代码和运行情况:

7e9e80c0ba81d4ffeed07bd20b941f1b.png

按照控制台提示,输入 value 的值之后,本该能够按照提示继续输入 choice 的值。但是你会发现程序直接跳过了 choice 的输入。而且 choice 原本的值是 'a',最后变成了换行符(即'n')。

造成这种现象的原因是 C 语言的输入缓冲区的机制。

什么是 C 语言的输入缓冲区呢?

输入分为两种,一种称为无缓冲输入(或直接输入),即你每输入一个字符,程序就读一个字符,并可立即使用这个字符;另一种称为缓冲输入,即将你一次性输入的所有字符先收集并存到缓冲区(buffer)里,在你按下 Enter 键之后将这些字符作为一个“块”全部给到程序。

为什么要使用缓冲区呢?

首先,把若干个字符作为一个块来传输比逐个发送字符更节约时间。其次,如果用户打错了字符,可以在输入区域修正,确认无误后按 Enter 键传入正确的输入。如果你使用的是无缓冲输入,那么一旦你打错字,这个错字符立刻就被传入到程序里了,这个时候想要改正就比较麻烦了。无缓冲输入一般在交互性强的程序里使用(比如实时游戏)。

缓冲分为两类:完全缓冲 I/O 和行缓冲 I/O。完全缓冲指的是当输入区被填满时才能刷新缓冲区,通常出现在文件输入中;行缓冲指的是在出现换行符时刷新缓冲区。键盘输入通常是行缓冲输入,所以在按下 Enter 键后才刷新缓冲区。

回到之前的问题。当我们输入 value 的值之后,我们敲了一下 Enter,将 value 的值传入,同时刷新了缓冲区。这里注意一个问题:scanf() 里的参数是 %d,要求读取 int 型变量。那么 scanf() 会跳过所有的空白字符,直到遇到第一个非空白字符。如果下一个字符是数字,那么 scanf() 继续读取;如果下一个字符不是数字,则 scanf() 认为读到了末尾,于是刷新缓存区,并将非数字字符放回缓存区

紧接着我们就要输入 choice 的值,这时在缓冲里的是残留的 Enter,也即换行符。那么 choice 作为一个字符类型的变量,接收到了残留在缓冲区里的 Enter,于是程序自动结束。

因此,如果要让 choice 读到我们输入的正确数据,我们必须要在输入 choice 之前把缓冲区清空

清空缓冲区的方法有如下三种:

  1. 使用 stdlib.h 提供的 fflush() 函数。那么原先的代码可以改成如下形式:

575b97e64251467f75002516fc0ae633.png

fflush() 不在 C/C++ 标准里,比如 Linux 下的 GCC 就不支持这个函数,因此这个方法的可移植性较差,不推荐使用这个方法

2. 使用 while((choice = getchar()) != 'n' && choice != EOF); 语句。这个方法的原理是循环地将缓冲区剩余的字符赋给 choice,直到将缓冲区里的换行符赋给了 choice 或者 choice = EOF 的时候,则跳出循环。此时缓冲区里没有任何字符。然后即可继续输入。

这个方法的优点是可移植性强,在任何平台上都能过编译。因为只用到了 C 语言的 while 循环。一般推荐使用这个方法。

原先的代码改成如下形式:

6b7ee7b8c789261578afb5bb76e3cd10.png

3. 使用 stdio.h 提供的 setbuf() 函数关闭缓冲区。

82475b3f102040ee0461f2a73d2b9175.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值