代码之家  ›  专栏  ›  技术社区  ›  Michael Kristofik

我需要将strtol的结果转换为int吗?

  •  4
  • Michael Kristofik  · 技术社区  · 16 年前

    以下代码对g++4.1.1和 -Wall .

    int octalStrToInt(const std::string& s)
    {    
        return strtol(s.c_str(), 0, 8);
    }
    

    因为strtol返回了 long int 但我的职责只是 int . 其他编译器可能在这里发出警告吗? 在这种情况下,我应该将返回值强制转换为int吗?

    5 回复  |  直到 16 年前
        1
  •  1
  •   UncleBens    16 年前

    您可能需要-wconversion标志来打开这些警告。但是,它不会警告 长的 -gt; int ,因为它们的大小与gcc相同(该值不会因为转换而更改)。但是如果你把它转换成 长的 -gt; 短的

    我想简单地做一个演员不会被推荐,因为那只会掩盖错误的可能性。检查这样的强制转换不会修改值以安抚编译器之后就可以了。

        2
  •  3
  •   Å imon Tóth    16 年前

    最好的方法是:

    long x = strtol(...); assert(x <= INT_MAX); return (int)x;

    你需要 limits.h assert.h

        3
  •  2
  •   Steve Jessop    16 年前

    如果你没有权限 boost::numeric_cast ,您可以编写一个简单的模拟:

    template <typename T, typename S>
    T range_check(const S &s) {
        assert(s <= std::numeric_limits<T>::max());
        assert(s >= std::numeric_limits<T>::min());
        return static_cast<T>(s); // explicit conversion, no warnings.
    }
    
    return range_check<int>(strtol(some_value,0,8));
    

    实际上这有点作弊,因为它不适用于浮点目的地类型。 min() 与整数类型的绑定不同,您需要检查+/- max() . 为读者做练习。

    是否使用assert或其他错误处理取决于您实际要对无效输入执行的操作。

    还有 boost::lexical_cast (我不知道怎么把它变成八进制)和stringstream。请阅读所需的类型,而不是碰巧具有C库函数的类型。

        4
  •  1
  •   user291562    16 年前

    这里没有任何警告,因为平台上的“int”和“long int”数据类型具有相同的大小和范围。根据架构的不同,它们可能会变得不同。

    为了避免出现奇怪的错误,请使用范围检查。我建议您使用STD::MultICIX限制::MI/MAX(见)。

    范围检查后,您可以安全地使用static_cast或c-style cast。

    另一方面,您也可以依赖于STD(:)类中实现的相同功能。STD::StrugSuffic将默认为平台安全和类型安全。

        5
  •  0
  •   John Dibling    16 年前

    大多数现代编译器都会根据您配置的警告级别对转换和可能的截断发出警告。在警告级别为4的MSVC上。

    最佳实践是从函数中返回long,并让调用代码决定如何处理转换。除此之外,至少要确保从strtol获得的值在返回之前符合int,正如let_me_be所建议的那样。

    推荐文章