tmi*_*hty 19 c++ type-conversion
我有以下字符串:
sThis = "2154910440";
unsigned int iStart=atoi(sThis.c_str());
Run Code Online (Sandbox Code Playgroud)
但结果是
iStart = 2147483647
Run Code Online (Sandbox Code Playgroud)
有人看到我的错误吗?
Ben*_*ley 35
atoi将字符串转换为int.在您的系统上,a int为32位,其最大值为2147483647.您尝试转换的值超出此范围,因此返回值atoi未定义.我想,你的实现会int在这种情况下返回a的最大值.
您可以改为使用atoll,返回long long,保证至少为64位.或者您可以使用来自stoi/stol/stoll系列的函数或其未签名的对应函数,这些函数实际上会以异常的形式提供有关超出范围值(和无效值)的有用错误报告.
我个人喜欢boost::lexical_cast.即使它看起来有点麻烦,但它可以用于更一般的上下文中.您可以在模板中使用它,只需转发类型参数,而不必具有特化
Ben*_*igt 10
您应该使用std::strtoul,找到<cstdlib>,为无符号数设计,范围更大,并更好地报告错误.
如果要将std::string输入和异常用于错误处理,请使用std::stoul.一个简短,高效的实施方案如下:
#include <string>
#include <stdexcept>
inline unsigned int stoui(const std::string& s)
{
unsigned long lresult = stoul(s, 0, 10);
unsigned int result = lresult;
if (result != lresult) throw std::out_of_range();
return result;
}
Run Code Online (Sandbox Code Playgroud)
这将比istringstream文化不变(因此在异常语言环境中运行时没有意外的行为更改),完全可移植以及使用第三个参数快得多,您可以支持不同的数字基础甚至执行检测0x和0前缀.
但是unsigned int不一定大到足以保持你的价值,所以使用unsigned long,然后你将不需要上面的包装.
atoi返回一个signed int,它在你的平台上的最大值为2^31-1.
你将结果分配给什么并不重要,它将受到返回类型的限制.
C++流可以读取无符号的整数.
std::istringstream reader(sThis);
unsigned int val;
reader >> val;
Run Code Online (Sandbox Code Playgroud)