热门话题

Php 研究室

流的使用之一:清空输入缓冲区、string类型转    作者:xieaotian发表于2009-05-22 15:47:28

	   

参考: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
T& toValue(const string& s, T& value) {
istringstream is(s);
is >> value;
if (is.fail()) {
value = 0;
}
return value;
}

///////////////

include
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

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

void main( void )
{
char buffer[200], s[] = "compute
, 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

回复主题
Copyright © 2008-2010 版权所属:中国Python联盟 www.okpython.com
京ICP备08012290号 村长QQ:81356625 E-mail:xieaotian@163.com