首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

如何清空cin缓冲区

2012-03-22 
怎么清空cin缓冲区有没有什么方法清空cin缓冲区里的数据。就如同endl的作用一样![解决办法]fflush (stdin)

怎么清空cin缓冲区
有没有什么方法清空cin缓冲区里的数据。就如同endl的作用一样!

[解决办法]
fflush (stdin)在c++标准中,未定义其返回,vc对其进行了扩充,但其他编译器不一定能通过编译。要写可移植的代码,可用以下方法来清空输入缓冲区。只需要在scanf函数后面加上几句简单的代码就可以了。

/*C版本*/
int main(void)
{
int i,c;
for(;;) {
fputs ( "Pleaseinputaninteger: ", stdout);
if(scanf( "%d ",&i)!=EOF) { /*如果用户输入的不是EOF*/

/*while循环会把输入缓冲中的残留字符清空*/
/*读者可以根据需要把它改成宏或者内联函数*/
/*注:C99中也定义了内联函数,gcc3.2支持*/

while ((c=getchar()) != '\n '&&c!=EOF) {
;
} /*endofwhile*/
}
printf ( "%d\n ", i);
return 0;
}

//C++版本
usingstd::cout;
usingstd::endl;
usingstd::cin;

int main()
{
int value;

for (; ;){
cout < < "Enteraninteger: ";
cin > > value;

/*读到非法字符后,输入流将处于出错状态,
*为了继续获取输入,首先要调用clear函数
*来清除输入流的错误标记,然后才能调用
*ignore函数来清除输入缓冲区中的数据。*/

cin.clear();

/*numeric_limits::max()返回缓冲区的大小。
*ignore函数在此将把输入缓冲区中的数据清空。
*这两个函数的具体用法请读者自行查询。*/

cin.ignore (std::numeric_limits::max(), '\n ');
cout <
}
return0;
}

对c版本做法的争议:

if (scanf ( "%d ", &i) != EOF) {
while ((c=getchar()) != '\n ' && c != EOF) {
;
}
}

并没有完全解决了问题,存在重大的漏洞。主要问题在于,使用getchar()这种方法并没有清除EOF标志。如果用tc2.0、tc2.01、tc3.0、tc3.1等等编译器运行上述代码,输入时用ctrl+z结尾或者直接输入ctrl+z,程序肯定会进入一个死循环!

原因就是getchar()方式并没有清除EOF标志,我在这里所说的EOF标志并非指函数返回的EOF,而是指当I/O函数遇到EOF时在其内部产生的EOF标志。

偶推荐用rewind (stdin)这个方法,rewind不仅清除了stdin中的内容,还清除EOF标志,用下列语句:

scanf ( "%d ", &i);
rewind (stdin);

代替上述if语句,无论你如何输入ctrl+z,都不会进入死循环,同时也简单得多,是比较完美的解决方法。

string类型转换

char*型的字符串可以用c++的 sprintf ,还有MFC的 CString::Format 也不错进行numberTostring的转换。

atof, atoi, atol, _ecvt, _fcvt, _itoa, _i64toa, _itow, _i64tow 这些也是用于char*型的转换numberTostring/stringTonumber。

对于标准c++的string型字符串,可以用以下方法进行类型转换。

stringTonumber

用istringstream,这里给个例子:
template <class T>
T& toValue(const string& s, T& value) {
istringstream is(s);
is > > value;
if (is.fail()) {
value = 0;
}
return value;
}

///////////////
#include <sstream.h>
string s = "12345 ";
int n = 0;
toValue(s, n);

附加一个例子:

istringstream iss( "#123 1.23 aaa ,zzz kk,k oo.jjj ");
cout < < iss.str() < < endl;

char ch;
iss > > ch;
cout < < ch < < endl;

iss > > i;
cout < < i < < endl;

float f;
iss > > f;
cout < < f < < endl;

char buf[1024];
iss > > buf;
cout < < buf < < endl;
cout < < "OK\n ";

iss.ignore (100, 'j '+1);
iss > > buf;
cout < < buf < < endl;


numberTostring

string a;

1、
ostringstream oss(a);
oss < < 999999;
a = oss.str ();

2、
stringstream ss (a);
ss < < 9;
ss > > a;
cout < < a;

3、
itoa (111, buf, 10); //十进制
a = buf; //char* 赋值到 string;




sscanf 的例子



#include <stdio.h>

void main( void )
{
char tokenstring[] = "15 12 14... ";
char s[81];
char c;
int i;
float fp;

/* Input various data from tokenstring: */
sscanf( tokenstring, "%s ", s );
sscanf( tokenstring, "%c ", &c );
sscanf( tokenstring, "%d ", &i );
sscanf( tokenstring, "%f ", &fp );

/* Output the data read */
printf( "String = %s\n ", s );
printf( "Character = %c\n ", c );
printf( "Integer: = %d\n ", i );
printf( "Real: = %f\n ", fp );
}

Output

String = 15Character = 1Integer: = 15Real: = 15.000000
sprintf 的例子

#include <stdio.h>

void main( void )
{
char buffer[200], s[] = "computer ", c = 'l ';
int i = 35, j;
float fp = 1.7320534f;

/* Format and print various data: */
j = sprintf( buffer, "\tString: %s\n ", s );
j += sprintf( buffer + j, "\tCharacter: %c\n ", c );
j += sprintf( buffer + j, "\tInteger: %d\n ", i );
j += sprintf( buffer + j, "\tReal: %f\n ", fp );

printf( "Output:\n%s\ncharacter count = %d\n ", buffer, j );
}

原文http://blog.csdn.net/BEN1978/archive/2006/06/29/850352.aspx
[解决办法]
搞错 ,类型没给出
cin.ignore((std::numeric_limits <int> ::max)(), '\n ');

热点排行