最近被atoi给坑了一次, 造成了一个“概率性”问题, 所以来聊一下。
平时经常要用到无符号整形(是unsigned int而不是int), 最近在简单的测试代码中用了一下atoi, NM, 一不小心就踩到坑了。实际上, 我是基本废弃使用这两个函数的。测试代码图简单就出差错了
为了便于简单说事, 我对程序进行极简化,先看代码:
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
int main()
{
string s = "3456754321";
unsigned int n = atoi(s.c_str());
cout << n << endl;
return 0;
}
结果为:
taoge@localhost test> g++ test.cpp
taoge@localhost test> ./a.out
2147483647
taoge@localhost test>
可见, 值被截断, 返回的是最大的INT.
还是别用丑陋的atoi吧, 用stringstream来搞, 如下:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
unsigned int stou(const string &str)
{
unsigned int n;
stringstream ssTmp;
ssTmp << str;
ssTmp >> n;
return n;
}
int main()
{
string s = "3456754321";
unsigned int n = stou(s);
cout << n << endl;
return 0;
}
结果如下:
taoge@localhost test> g++ test.cpp
taoge@localhost test> ./a.out
3456754321
taoge@localhost test>
当然, 我们也可以对代码稍作修改, 如下:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
unsigned int stou(const string &str)
{
unsigned int n;
stringstream ssTmp(str);
ssTmp >> n;
return n;
}
int main()
{
string s = "3456754321";
unsigned int n = stou(s);
cout << n << endl;
return 0;
}
结果如下:
taoge@localhost test> g++ test.cpp
taoge@localhost test> ./a.out
3456754321
taoge@localhost test>
再来看看itoa, 还要去查什么函数用法, 我也是醉了, 所以懒得看了。 可以考虑用安全的snprintf, 另外, 我也推荐使用stringstream来做, 如下:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
string utos(unsigned int n)
{
string sResult;
stringstream ssTmp;
ssTmp << n;
ssTmp >> sResult;
return sResult;
}
int main()
{
unsigned int n = 3456754321;
string s = utos(n);
cout << s << endl;
return 0;
}
结果如下(warning不影响, 所以就不关注了):
taoge@localhost test> g++ test.cpp
test.cpp:19: warning: this decimal constant is unsigned only in ISO C90
taoge@localhost test> ./a.out
3456754321
taoge@localhost test>
程序稍作修改后如下:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
string utos(unsigned int n)
{
string sResult;
stringstream ssTmp;
ssTmp << n;
sResult = ssTmp.str();
return sResult;
}
int main()
{
unsigned int n = 3456754321;
string s = utos(n);
cout << s << endl;
return 0;
}
结果如下:
taoge@localhost test> g++ test.cpp
test.cpp:19: warning: this decimal constant is unsigned only in ISO C90
taoge@localhost test> ./a.out
3456754321
taoge@localhost test>
最后强调一下, 在涉及到无符号整形的时候, 要杜绝使用atoi和itoa