std :: iStream到未签名的数值,如何检测负值

std::istream to unsigned numerical value, how to detect negative values?

本文关键字:何检测 检测 iStream std      更新时间:2023-10-16

我正在研究模板功能,将字符串转换为一个数字,以编译某些不带C 11的遗留代码。

功能是:

template<typename T>
void checkValid( const std::string& val )
{
    std::stringstream str1;
    T temp1;
    str1 << val;
    str1 >> temp1;
    if ( str1.fail() || str1.bad() )
        std::cout << "error, " << val << " is not a valid string value" << std::endl;
    else
        std::cout << "ok, " << val << " is converted to " << temp1 << std::endl;
}

它运行良好,除了负值:

// valid integer
checkValid<int>( "3" );
// valid integer
checkValid<int>( "-1000" );
// invalid integer
checkValid<int>( "foo" );
// invalid integer out of range (>INT_MAX)
checkValid<int>( "8393930300303" );
// invalid integer out of range (<INT_MIN)
checkValid<int>( "-8393930300303" );
// valid unsigned integer
checkValid<unsigned int>( "3" );
// invalid unsigned integer
checkValid<unsigned int>( "foo" );
// unsigned integer out of range (>UINT_MAX)
checkValid<unsigned int>( "8393930300303" );
// unsigned integer out of range (<0)
checkValid<unsigned int>( "-3" );

此输出:

ok, 3 is converted to 3
ok, -1000 is converted to -1000
error, foo is not a valid string value
error, 8393930300303 is not a valid string value
error, -8393930300303 is not a valid string value
ok, 3 is converted to 3
error, foo is not a valid string value
error, 8393930300303 is not a valid string value
ok, -3 is converted to 4294967293

我期望的是最后一行:

error, -3 is not a valid string value
当目标类型未符号时,

负字符串值未正确处理。修复checkValid的最佳策略是什么是所有类型(签名的,未签名的数值和浮动/double(的预期的最佳策略?

允许流的无符号类型的负数。它具有与

相同的机制
unsigned type foo = -some_value

由于它们可以接受负数,因此流将永远不会失败,您将具有将负数分配给无符号类型的正常行为。

,我们可以在您的功能中添加此检查。对于T类型,T() - T(1) < 0,只有在签名类型时才是正确的,否则减法将缠绕并成为最大的值T代表。因此,如果我们检查该条件,并且字符串以'-'开头,那么您就会知道它不是"有效"值。这使您的功能看起来像

template<typename T>
void checkValid( const std::string& val )
{
    std::stringstream str1;
    T temp1;
    str1 << val;
    str1 >> temp1;
    if ( str1.fail() || str1.bad() || (!(T() - T(1) < T()) && val[0] == '-')  )
        std::cout << "error, " << val << " is not a valid string value" << std::endl;
    else
        std::cout << "ok, " << val << " is converted to " << temp1 << std::endl;
}

如果您的字符串可以具有领先的空格,则您需要用val[val.find_first_not_of(" ")] == '-'

替换val[0] == '-'检查