C++ C++;11:当前导字符为alpha(abcdef)时,如何从stringstream解析十六进制字符串

C++ C++;11:当前导字符为alpha(abcdef)时,如何从stringstream解析十六进制字符串,c++,c++11,hex,stringstream,C++,C++11,Hex,Stringstream,我正试图根据上的示例从std::stringstream读取十六进制值。当字符串的前导字符是数字字符[0-9]时,一切正常,但当前导字符是字母字符[a-f,a-f]时,从流中获取值会消耗字符,但不会为整数赋值。是否需要设置一个标志或某些东西来告诉stringstream或std::hex这实际上是一个有效的十六进制值,并且应该这样解释 我可能最终只是将数据流读入一个字符串并使用std::stoi,但我想知道为什么直接从stringstream解析不起作用,或者是否有办法让它起作用 示例代码: #

我正试图根据上的示例从std::stringstream读取十六进制值。当字符串的前导字符是数字字符[0-9]时,一切正常,但当前导字符是字母字符[a-f,a-f]时,从流中获取值会消耗字符,但不会为整数赋值。是否需要设置一个标志或某些东西来告诉stringstream或std::hex这实际上是一个有效的十六进制值,并且应该这样解释

我可能最终只是将数据流读入一个字符串并使用std::stoi,但我想知道为什么直接从stringstream解析不起作用,或者是否有办法让它起作用

示例代码:

#include <iostream>
#include <sstream>
#include <string>
int main()
{
    int anint = 0;
    std::stringstream ss;
    ss.str("1234abcd");
    ss >> std::hex >> anint;
    printf("anint = %x\n", anint);

    anint = 0;
    ss.str("a234abcd");
    ss >> std::hex >> anint;
    printf("anint = %x\n", anint);

    return 0;
}
代码中的(主要)问题是,在第一次读取字符串流之后,没有清除
EOF
标志!此外,如果您的系统使用32位
int
类型,则值
a234abcd
将溢出,并且您(可能)将获得
0x7FFFFFFF
(即
int\u MAX
)的值

以下代码给出了(我认为)您想要的:

#包括
#包括
#包括
int main()
{
int-anint=0;
std::stringstream-ss;
ss.str(“1234abcd”);
ss>>std::hex>>anint;
printf(“anint=%x\n”,anint);
ss.clear();//清除EOF标志!
anint=0;
//ss.str(“a234abcd”);//将溢出32位int!
ss.str(“a234abc”);//工作正常
ss>>std::hex>>anint;
printf(“anint=%x\n”,anint);
返回0;
}

请随时要求进一步的澄清和/或解释。

我编辑了上面提到的@Adrian Mole这样的代码,现在我看到了更有意义的结果。结果我只需要读取一个无符号的int

编辑代码

#include <iostream>
#include <sstream>
#include <string>

int main()
{
    int anint1 = 0;
    std::stringstream ss1;
    ss1.str("1234abcd");
    ss1 >> std::hex >> anint1;
    printf("anint = %x\n", anint1);

    int anint2 = 0;
    std::stringstream ss2;
    ss2.str("a234abcd");
    ss2 >> std::hex >> anint2;
    printf("anint = %x\n", anint2);

    unsigned int anunint = 0;
    std::stringstream ss3;
    ss3.str("a234abcd");
    ss3 >> std::hex >> anunint;
    printf("anunint = %x\n", anunint);

    return 0;
}

这问题中的测试被打破了,真的!但是我找不到一个明确的参考来解释为什么
ss>>std::hex>>anint
不能正确地将OP的原始值解释为负数,而不是溢出并给出
MAX\u INT
。因为它不是负数。别忘了签名溢出不是一个定义良好的东西。它不像无符号值那样环绕。你可能过于相信过去所看到的UB的一些实际症状。IOStream库不是为触发UB而设计的。将值标记为超出范围是“正确的”。不,这一点也不奇怪。OP的原始值不是负数,因此没有理由期望从中解析负数。更一般地说,这也可能是在不需要时重复使用对象的风险的教训。目前我的审美/习惯是,我会将这两个测试放在它们自己的块范围内(即在它们周围添加
{
}
),这是理所当然的。这完全可以防止类似这样的错误。在回答问题后,请不要从根本上改变问题。我已回滚您的编辑。谢谢你,谢谢你的澄清。它本来是一个玩具般的例子,所以我没有像最初那样努力避免重用变量。希望这次我能把它编辑得更好,这样人们在遇到类似问题时可以得到帮助。@swithwings似乎你的回滚没有持续很久。不知道接下来会发生什么?@AdrianMole我放弃了,把手术留给它。
#include <iostream>
#include <sstream>
#include <string>

int main()
{
    int anint1 = 0;
    std::stringstream ss1;
    ss1.str("1234abcd");
    ss1 >> std::hex >> anint1;
    printf("anint = %x\n", anint1);

    int anint2 = 0;
    std::stringstream ss2;
    ss2.str("a234abcd");
    ss2 >> std::hex >> anint2;
    printf("anint = %x\n", anint2);

    unsigned int anunint = 0;
    std::stringstream ss3;
    ss3.str("a234abcd");
    ss3 >> std::hex >> anunint;
    printf("anunint = %x\n", anunint);

    return 0;
}
anint = 1234abcd
anint = 7fffffff
anunint = a234abcd