从istream中读取int,检测溢出



如果使用>>操作符从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;
}

这样做在思想上是正确的?

对于一般的解析失败(包括数目过大或过小),您可以简单地检查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;
    }
}

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

boost::lexical_cast是一个很好的库。如果值不适合目标类型,它将抛出异常。

相关内容

  • 没有找到相关文章

最新更新