2015-02-09 117 views
3

使用std :: setbase格式化数字以将int的数字最小值传递给std :: stoi抛出std :: out_of_range异常,但我不懂为什么。如果有人能帮助我更好地理解异常背后的原因,我将不胜感激。std :: stoi,std :: setbase和std :: out_of_range错误

代码段:

#include <iomanip> 
#include <iostream> 
#include <limits> 
#include <sstream> 

template <typename T> 
std::string toString(const T x, const int base) 
{ 
    std::stringstream ss; 
    ss << std::setbase(base) << x; 
    return ss.str(); 
} 

int main(void) 
{ 
    const int x = std::numeric_limits<int>::min(); 
    std::size_t index = 0; 
    const auto base = 16; 
    const auto s = toString(x, base); 
    std::cout << "base-10: " << x << std::endl 
       << "base-" << base << ": " << s << std::endl; 
    std::cout << std::stoi(s, &index, base) << std::endl; 
    return 0; 
} 

输出:

base-10: -2147483648 
base-16: 80000000 
terminate called after throwing an instance of 'std::out_of_range' 
    what(): stoi 
Aborted (core dumped) 
+0

@ildjarn - 张贴作为答案,我可以为你upvote它:) – LThode 2015-02-09 21:29:35

+0

我找不到任何引用是否使用ss“std :: setbase(16)<< x;'是一个坏的想法负面'x'。即使对于'x = -10;'我也会看到使用你的代码的问题。来自'ss << std :: setbase(base)<< x;'的字符串是'fffffff6',这对int来说可能也太大了。 – 2015-02-09 21:33:37

+1

这是因为不一致:“std :: setbase(16)”或“std :: hex”将数字转换为无符号数,而“std :: stoi”处理有符号数。 – interjay 2015-02-09 21:35:49

回答

6

std::stoX功能不会为不与-前缀字符串返回一个负值。 0x80000000是2 ,这是不能表示一个有符号的32位整数,所以有溢出,因此引发异常。