为什么fflush(stdin)用了并不能清除缓冲区
很多人在教材上都看到fflush(stdin)这个函数的使用,教材给出的解释是清除缓冲区,可是一些动手实践过代码的小伙伴发现,fflush(stdin)这个函数并没有起到清除缓冲区的作用,那这是什么原因呢?
教材中fflush(stdin)的来源
fflush(stdin)这个函数官方给出的解释是:由Microsoft官方提供的MSDN 文档里清楚地写着:fflush on input stream is an extension to the C standard。这仅仅是对于C语言的一种扩展,而并不是C语言内置的系统函数,而这种扩展的函数在当时能够实现清除缓冲区的功能,所以当时在需要清除缓冲区的时候就使用fflush(stdin)来清除缓冲区,然而教材一般都是版本比较老的,所有也就这样地写到。
为什么现在不能够使用了
在解释教材中为什么出现fflush(stdin)中也特意使用了当时这一词。因为在现在和当时使用fflush(stdin)的情况不一样了,在C11之前,fflush(stdin)还能够使用,并且是实现清除缓冲区的功能,但是在C11之后,fflush(stdin)已经被删除了,就是起不到清除缓冲区的功能了。至于为什么删除,是因为fflush(stdin)这个函数对于缓冲区并没有很好的解决,这里也不去深究。
那么现在如何清除缓冲区呢
现在主流的方法主要为两个:
- 使用rewind(stdin);
这个函数与fflush(stdin)很相似,应该是fflush(stdin)的改版。这个虽然也不是标准的定义函数,但是现在也没有很好的解决方法,也是将fflush(stdin)清除功能后的一个补充。 - 使用scanf("%*[^\n]%*c");
给出对于这个输入函数的一个解释: %*[^\n]将逐个读取缓冲区中的’\n’字符之前的其它字符,%后面的*表示将读取的这些字符丢弃,前遇到’\n’字符时便停止读取操作,此时,缓冲区中尚有一个’\n’字符遗留,所以后面的%*c将读取并丢弃这个遗留的换行符,这里的星号和前面的星号作用相同。由于所有从键盘的输入都是以回车结束的,而回车会产生一个’\n’字符,所以将’\n’连同它之前的字符全部读取并丢弃之后,也就相当于清除了输入缓冲区。
缓冲区刷新条件
- 缓冲区满时
- 执行flush语句
- 执行endl语句
- 关闭文件
使用fflush(stdin)注意事项
如果实在想试试穿越时空的功能,在使用fflush(stdin)时,必须保证你的编译环境在C11以前,如果你使用得当编译器是Visual Studio,那么就注意下你的Visual Studio的版本,在Visual Studio 2015以前,这个函数都是能够使用的,但是在Visual Studio 2015以后,包括Visual Studio 2015,这个函数已经确切地被取消这一功能了。