参考:http://www.programfan.com/club/showbbs.asp?id=176827
清空输入缓冲区的方法
在获取用户输入时,如果发生类型不匹配的错误,输入设备对象将处在出错状态,不能继续输入信息。例如,cin >> i; 输入一个字幕'a',就会出现错误。这时,需要清空输入缓冲区,以继续输入信息。
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 = 15
Character = 1
Integer: = 15
Real: = 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 );
}
Output
Output: String: computer Character: l Integer: 35 Real: 1.732053 character count = 71