将字符串中以十六进制存储的负长值转换为C ++中的长变量

时间:2018-05-01 04:18:37

标签: c++ stream

我正在尝试将十六进制的字符串流转换为long。我来到这里寻求帮助,他们给出的解决方案(适用于short,int和大多数longs)不适用于需要至少16位十六进制数字表示的负数。

基本上我有一个名为hx的字符串流,我填充了十六进制数字,应该等于-9223372036854775808

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

using namespace std;

int main() {
    stringstream hx;
    hx << hex << LONG_MIN;
    cout << hx.str() << '\n';

    long value;
    hx >> value;

    cout << value << '\n';
    return 0;
}

实际输出:

8000000000000000
9223372036854775807

预期产出:

8000000000000000
-9223372036854775808

当符号位为1时,我看不出为什么十六进制值被转换为正数。

2 个答案:

答案 0 :(得分:0)

首先,hx << hex << LONG_MIN将隐式使用printf("%lx", ...)来打印值results in undefined behavior,因为LONG_MIN不属于unsigned long类型。

其次,让我们说hx.str()现在存储字符串8000000000000000。为了输入value,它被解释为一个很大的数字。因此,std::numeric_limits<long>::max(),即9223372036854775807 is stored in value

答案 1 :(得分:0)

以下是其他答案中解释的解决方案和推理hx&lt;&lt; hex&lt;&lt; LONG_MIN将隐式使用printf(&#34;%lx&#34;,...),其类型为unsigned long:

int main() {
    stringstream hx;
    hx <<hex << (LONG_MIN);
    cout << hx.str() << '\n';

    unsigned long value;
    hx >> value;

    cout << static_cast<long>( value ) << '\n';
    return 0;
}