1. 为何 fflush(stdin) 是错的linux
首先请看如下程序:ios
#include <stdio.h>ide
int main( void )函数
{操作系统
int i;ci
for (;;) {文档
fputs("Please input an integer: ", stdout);get
scanf("%d", &i);input
printf("%d\n", i);编译器
}
return 0;
}
这个程序首先会提示用户输入一个整数,而后等待用户输入,若是用户输入的是整数,程序会输出刚才输入的整数,而且再次提示用户输入一个整数,而后等待用户输入。可是一旦用户输入的不是整数(如小数或者字母),假设 scanf 函数最后一次获得的整数是 2 ,那么程序会不停地输出“Please input an integer: 2”。这是由于 scanf("%d", &i); 只能接受整数,若是用户输入了字母,则这个字母会遗留在“输入缓冲区”中。由于缓冲中有数据,故而 scanf 函数不会等待用户输入,直接就去缓冲中读取,但是缓冲中的倒是字母,这个字母再次被遗留在缓冲中,如此反复,从而致使不停地输出“Please input an integer: 2”。
也许有人会说:“竟然这样,那么在 scanf 函数后面加上‘fflush(stdin);’,把输入缓冲清空掉不就好了?”然而这是错的!C和C++的标准里历来没有定义过 fflush(stdin)。也许有人会说:“但是我用 fflush(stdin) 解决了这个问题,你怎么能说是错的呢?”的确,某些编译器(如VC6)支持用 fflush(stdin) 来清空输入缓冲,可是并不是全部编译器都要支持这个功能(linux 下的 gcc 就不支持),由于标准中根本没有定义 fflush(stdin)。MSDN 文档里也清楚地写着fflush on input stream is an extension to the C standard(fflush 操做输入流是对 C 标准的扩充)。固然,若是你绝不在意程序的移植性,用 fflush(stdin) 也没什么大问题。如下是 C99 对 fflush 函数的定义:
int fflush(FILE *stream);
若是 stream 指向输出流或者更新流(update stream),而且这个更新流
最近执行的操做不是输入,那么 fflush 函数将把这个流中任何待写数据传送至
宿主环境(host environment)写入文件。不然,它的行为是未定义的。
原文以下:
int fflush(FILE *stream);
If stream points to an output stream or an update stream in which
the most recent operation was not input, the fflush function causes
any unwritten data for that stream to be delivered to the host environment
to be written to the file; otherwise, the behavior is undefined.
其中,宿主环境能够理解为操做系统或内核等。
由此可知,若是 stream 指向输入流(如 stdin),那么 fflush 函数的行为是不肯定的。故而使用 fflush(stdin) 是不正确的,至少是移植性很差的。
2. 清空输入缓冲区的方法
虽然不能够用 fflush(stdin),可是咱们能够本身写代码来清空输入缓冲区。只须要在 scanf 函数后面加上几句简单的代码就能够了。
/* C 版本 */
#include <stdio.h>
int main( void )
{
int i, c;
for ( ; ; )
{
fputs("Please input an integer: ", stdout);
scanf("%d", &i);
if ( feof(stdin) || ferror(stdin) )
{ /* 若是用户输入文件结束标志(或文件已被读完), */
/* 或者发生读写错误,则退出循环 */
/* do something */
break;
}
/* 没有发生错误,清空输入流。 */
/* 经过 while 循环把输入流中的余留数据“吃”掉 */
while ( (c = getchar()) != '\n' && c != EOF ) ;
/* 使用 scanf("%*[^\n]"); 也能够清空输入流, */
/* 不过会残留 \n 字符。 */
printf("%d\n", i);
}
return 0;
}
/* C++ 版本 */
#include <iostream>
#include <limits> // 为了使用numeric_limits
using std::cout;
using std::endl;
using std::cin;
using std::numeric_limits;
using std::streamsize;
int main()
{
int value;
for ( ; ; )
{
cout << "Enter an integer: ";
cin >> value;
if ( cin.eof() || cin.bad() )
{ // 若是用户输入文件结束标志(或文件已被读完),
// 或者发生读写错误,则退出循环
// do something
break;
}
// 读到非法字符后,输入流将处于出错状态,
// 为了继续获取输入,首先要调用 clear 函数
// 来清除输入流的错误标记,而后才能调用
// ignore 函数来清除输入流中的数据。
cin.clear();
// numeric_limits<streamsize>::max() 返回输入缓冲的大小。
// ignore 函数在此将把输入流中的数据清空。
// 这两个函数的具体用法请读者自行查询。
cin.ignore( numeric_limits<streamsize>::max(), '\n' );
cout << value << '\n';
}
return 0;
}
参考资料:
ISO/IEC 9899:1999 (E) Programming languages— C 7.19.5.2 The fflush function
The C Programming Language 2nd Edition By Kernighan & Ritchie
ISO/IEC 14882(1998-9-01)Programming languages — C++
@2006-2-26 22:48 hxmzlgz
fflush(stdin);语句的做用
#include
#include
void main()
{float com=0.0,sale;int i;
char grade;
clrscr();
printf("\n Enter sale:");
scanf("%f",&sale);
fflush(stdin);
printf("\n Enter grade:");
scanf("%c",&grade);
if(sale>10000)
if(grade=='A')
com=sale*0.1 ;
else
com=sale*0.08 ;
else
com=sale*0.05;
printf("\n Com=%f",com);
}