如何在读取无符号整数时检测负数作为解析错误?

时间:2011-10-06 16:03:42

标签: c++ iostream

我希望从C ++ iostream中读取基数为10(十进制)表示的无符号整数,并至少检测到基本错误。在我看来,减号在这种情况下显然是一个错误,因为无符号整数没有任何符号。但是,gcc的观点不同:

#include <iostream>
#include <sstream>

int main() {
    std::stringstream a("5"), b("-0"), c("-4");
    unsigned int i;
    a >> i; if ( a ) std::cout << i << std::endl; else std::cout << "Conversion failure" << std::endl;
    b >> i; if ( b ) std::cout << i << std::endl; else std::cout << "Conversion failure" << std::endl;
    c >> i; if ( c ) std::cout << i << std::endl; else std::cout << "Conversion failure" << std::endl;
    return 0;
}

给我输出

4294967292

表示最后一行,好像已读取有符号整数-4并将其转换为unsigned int。

Apparently, the GCC people see this as a feature。是否有一些标准要求这种行为,并且有没有办法编写一个自己的解析器来摆脱它,即检测“-4”(可能是“-0”)作为转换错误?

3 个答案:

答案 0 :(得分:6)

咨询C ++ 03,22.2.2.1.2 / 11,这些格式是从scanf和朋友那里继承而来的,而这些格式又说转换后的字符序列是“可选的签名”,即使对于那些无符号输出。 strtoul是一样的。

所以,我想你可以说强制行为的标准是C ++ 03的C89,C ++ 11的C99。

由于-恰好只允许作为第一个字符,因此我认为解决方法是在使用peek之前使用operator>>进行检查。

答案 1 :(得分:0)

如果我正确地阅读了22.2.2.1.2 /表5,则表明提取到无符号相当于scanf %u,而显示负数 - &GT;积极转换。

答案 2 :(得分:-1)

如果你这样做会有什么不同吗?

int i;
unsigned int u;
c >> i;
u = i;
std :: cout << u;

operator>>容忍符号不匹配并不重要,因为基础C规则在任何情况下都允许静默转换。通过“加强”输入操作符,你并没有从根本上增加任何安全性。

那就是说, 我的 gcc(Solaris上的4.3.5)说这是转换错误。