我希望从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”)作为转换错误?
答案 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)说这是转换错误。