提问人:m88 提问时间:9/9/2019 最后编辑:xskxzrm88 更新时间:9/10/2019 访问量:220
使用 std::istream::operator>>处理无符号类型时,如何区分失败的提取和下溢?
With std::istream::operator>> working on unsigned types, how do I tell apart a failed extraction from an underflow?
问:
我想使用 std::istream::operator>> 将数据提取到无符号类型中(在模板中,因此它可以是 ushort、uint 等)。具体来说,我正在使用 std::stringstream 来解析从带有 std::getline() 调用的文件中提取的 std::string 行。
由于我正在从文件中读取,因此这些提取可能会因不同的原因而失败:下溢、溢出和“错误提取”。此类案件由STL处理:
如果提取失败,则将零写入值并设置 failbit。如果提取导致值过大或过小而无法容纳值,则写入 std::numeric_limits::max() 或 std::numeric_limits::min() 并设置 failbit 标志。
问题:对于无符号类型,std::numeric_limits::min() 等于 0,因此无法知道我是否正在读取不是整数的内容(在这种情况下,我正在中止程序)或者它是否只是一个下溢(在这种情况下,我只是限制值并发出警告)。
如何在不使用我正在使用的无符号类型的更大和/或有符号的等效项的情况下解决此问题?
答:
1赞
xskxzr
9/10/2019
#1
无符号类型不会下溢。如果输入负数来表示“下溢”,则标准流不会将其视为错误。负数被换行到无符号类型中,并且未设置。failbit
因此,如果您看到 0 已存储并已设置,则可以断言这是提取失败。要检测负数错误,您必须做一些额外的工作。例如,可以首先读取(足够大的)有符号整数类型的值,以检测它是否为负数。failbit
评论
0赞
m88
9/10/2019
事实上,我做了一些研究,似乎 std::strtoull() 正如您所描述的那样工作。引用:“如果减号是输入序列的一部分,则从数字序列计算出的数值将被否定,就像结果类型中的一元减号一样,这应用了无符号整数环绕规则”。由于 istream::operator>> 是(间接)基于它的,因此有理由认为它以相同的方式工作。
评论
std::istream::operator>>