std :: istream为无符号数值,如何检测负值?

时间:2018-04-03 14:10:45

标签: c++ stream

我正在使用模板函数将字符串转换为数字,以便在没有C ++ 11的情况下编译一些遗留代码。

功能是:

Option Explicit

Public Sub DeleteSpacesAndInsertEnter()
    Application.ScreenUpdating = False

    Selection.SetRange Selection.Start, Selection.Start + 1
    If Asc(Selection.Text) = 32 Or Asc(Selection.Text) = 160 Then
        Do While Asc(Selection.Text) = 32 Or Asc(Selection.Text) = 160
            Selection.MoveRight Unit:=wdCharacter, Count:=1
            Selection.TypeBackspace
            Selection.SetRange Selection.Start, Selection.Start + 1
        Loop
        Selection.MoveLeft Unit:=wdCharacter, Count:=1
        Selection.TypeParagraph
    End If

    Application.ScreenUpdating = True
End Sub

除负值外,它的效果非常好:

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 并使其对所有类型(有符号,无符号数字,还有浮点数/双精度)的预期行为的最佳策略是什么?

1 个答案:

答案 0 :(得分:1)

允许Streams为无符号类型取负数。它具有与

相同的机制
unsigned type foo = -some_value

由于它们可以输入负数,因此流不会失败,并且您将具有为无符号类型指定负数的正常行为。

我们可以在你的函数中添加一个检查。对于类型TT() - T(1) < 0,只有在类型被签名时才会为true,否则减法将会回绕并成为T可以表示的最大值。所以,如果我们检查那个条件,并且字符串以'-'开头,那么你知道它不是&#34;有效的&#34;值。这使你的功能看起来像

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[0] == '-'检查替换为val[val.find_first_not_of(" ")] == '-'

之类的内容