6

如果我使用 >> 运算符从 istream 中读取一个整数,并且表示的整数大于 INT_MAX,则该操作只返回 INT_MAX。

我目前正在与 INT_MAX 进行比较以检测溢出,但是如果输入操作“2147483647”,那么它将返回错误,而实际上没有错误并且结果有效。

示例:http: //ideone.com/4bXyGd

#include <iostream>
#include <sstream>
#include <climits>

int main() {
    std::istringstream st("1234567890123"); // Try with 2147483647
    int result;

    st >> result;

    if (result == INT_MAX)
        std::cout << "Overflow!" << std::endl;
    else
        std::cout << result << std::endl;

    return 0;
}

这样做的意识形态正确方法是什么?

4

2 回答 2

10

对于一般的解析失败(包括数字太大或太小),您可以简单地检查 stringstream 的失败位是否已设置。最简单的方法是:

if (!st) {
    std::cout << "Could not parse number" << std::endl;
}

在 C++11 之前,无法使用此方法专门检查上溢或下溢。但是在 C++11 中,如果解析的值对于该类型来说太大或太小,除了设置失败位之外,结果将被设置为该类型可以容纳的最大值(std::numeric_limits<Type>::max()或)。std::numeric_limits<Type>::min()

因此,在 C++11 中检查值是否太大或太小,您可以执行以下操作:

if (!st) {
    if (result == std::numeric_limits<int>::max()) {
        std::cout << "Overflow!" << std::endl;
    } else if (result == std::numeric_limits<int>::min()) {
        std::cout << "Underflow!" << std::endl;
    } else {
        std::cout << "Some other parse error" << std::endl;
    }
}
于 2013-06-14T20:37:21.930 回答
1

最好的方法是将值作为字符串读取,然后将其转换为整数。在转换过程中,您可以了解该值是否适合您要转换的类型的范围。

boost::lexical_cast是一个很好的图书馆。如果值不适合目标类型,它将引发异常。

于 2013-06-14T20:29:23.430 回答