无意中查到模块中这个小小的函数,用于把 string 转换成 int,按理说,在 java 之类的语言中是很简单的事情,可是 C++ 里还有点麻烦。本来以为按别人的做法就行了,却发现有点问题。我把原本模块中使用的方法和我自己找到的另一种方法做了个对比,看看吧。
#include <string>
#include <strstream>
int StrToInt1(const string &s);
int StrToInt2(const string &s);
int main(){
int retInt1, retInt2;
string myStr = "";
retInt1 = StrToInt1(myStr);
retInt2 = StrToInt2(myStr);
myStr = "216";
retInt1 = StrToInt1(myStr);
retInt2 = StrToInt2(myStr);
myStr = "";
retInt1 = StrToInt1(myStr);
retInt2 = StrToInt2(myStr);
myStr = " -1240 ";
retInt1 = StrToInt1(myStr);
retInt2 = StrToInt2(myStr);
myStr = " -1 2 4 0 ";
retInt1 = StrToInt1(myStr);
retInt2 = StrToInt2(myStr);
myStr = " a -1 240 ";
retInt1 = StrToInt1(myStr);
retInt2 = StrToInt2(myStr);
return 0;
}
int StrToInt1( const string &s )
{
//int ret = 0;
int ret;
istrstream is( s.c_str() );
is>>ret;
cout << "StrToInt1(): string s = " << s << ", int ret = " << ret << endl;
return( ret );
}
int StrToInt2( const string &s )
{
int ret = atoi(s.c_str());
cout << "StrToInt2(): string s = " << s << ", int ret = " << ret << endl;
return( ret );
}
运行的结果如下:
StrToInt1(): string s = , int ret = 201024
StrToInt2(): string s = , int ret = 0
StrToInt1(): string s = 216, int ret = 216
StrToInt2(): string s = 216, int ret = 216
StrToInt1(): string s = , int ret = 216
StrToInt2(): string s = , int ret = 0
StrToInt1(): string s = -1240 , int ret = -1240
StrToInt2(): string s = -1240 , int ret = -1240
StrToInt1(): string s = -1 2 4 0 , int ret = -1
StrToInt2(): string s = -1 2 4 0 , int ret = -1
StrToInt1(): string s = a -1 240 , int ret = -1
StrToInt2(): string s = a -1 240 , int ret = 0
看出区别来了么?
用 istrstream 的话,如果 string s 为空,那么 int ret 是取内存里前一个 integer 的值,例如第一次调用 StrToInt1() 时,返回的就是一个随机数(这个我不是很确定,也许并不是随机的,也许就是内存里的前一个值)。如果事先给 retInt1 或 ret 初始化赋了一个值,那么如果 string s 为空,得到的就是初始化的那个值。如果输入的 string 有不是数字的东西,istrstream 不会返回任何值,于是就把之前的一个数字作为返回,跟输入了空字符串的效果一样。
而使用 atoi 的话,如果 string s 为空,那么 int ret 返回为0。如果输入的 string 有不是数字的东西,看得出来,atoi 返回的还是0。
这样的话,两种方法都有利有弊,如果这两种函数能有一种变量,专门作为 invalid return 的值就好了。所以现在使用他们的话,只能尽量控制输入的 string,用 istrstream 的时候就尽量保证输入的 string 不为空也不为无效字符串。而 atoi 还算好,只不过无法区分 string 本身为 "0" 和空/无效的区别而已。