当前位置:  开发笔记 > 编程语言 > 正文

当>> operator尝试输入大于变量的值时,会发生什么?

如何解决《当>>operator尝试输入大于变量的值时,会发生什么?》经验,为你挑选了2个好方法。

我从文本文件中提取数字并用它们填充int类型的数组.

我正在将值插入到数组中,同时使用这些代码行循环遍历.txt文件(其中k是.txt文件中的数字量):

for (int j = 0; j < k; j++)
  inputFile >> tab[j];

当文本文件中的数字小于2,147,483,647时,这是整数类型的最大大小,一切顺利.

当数字大于这个程序时,我假设溢出并且无法插入它,但它之后也无法插入任何数字.

导致溢出发生后不再插入数字的原因是什么?



1> Jerry Coffin..:

该标准要求如果输入值超出范围,则将最近的可用值写入目标,并设置流failbit.具体要求(来自[istream.formatted.arithmetic]/3)是:

operator>>(int& val);

转换发生时好像由以下代码片段执行[...]:

iostate err = ios_base::goodbit;
long lval;
use_facet(loc).get(*this, 0, *this, err, lval);
if (lval < numeric_limits::min()) {
    err |= ios_base::failbit;
    val = numeric_limits::min();
}
else if (numeric_limits::max() < lval) {
    err |= ios_base::failbit;
    val = numeric_limits::max();
}
else
    val = static_cast(lval);
setstate(err);

一旦设置了流的failbit,它就会"粘滞",所以进一步尝试提取数据都将立即失败,直到故障清除被清除.



2> jaggedSpire..:

std::istream& std::istream::operator>>(std::istream&, int&),cppreference说:

表现为FormattedInputFunction.在构造和检查可能跳过前导空格的sentry对象之后,通过调用提取整数值std::num_get::get()

...

如果提取失败,则将零写入值并设置failbit.如果提取导致值太大或太小而无法拟合值,std::numeric_limits::max()或者std::numeric_limits::min()被写入并且设置了failbit标志.(自c ++ 11起)

它不是规范性的,但它确实提供了对这里发生的事情的一个很好的总结.

FormattedInputFunctions将从流构造一个哨兵并检查该值.如果sentry对象的计算结果为false,则不执行任何输入.

对于正在操作的流具有false故障点设置,在其他情况下,哨兵对象将进行评估.


那么,发生了什么:

    流尝试读入一个太大而不能保存在int数据类型中的整数.

    int传递到它的功能设置为最大可能值int可以存储.

    传递给函数的流具有其failbit集.

    对流的进一步读取失败并且不执行任何操作,因为已设置流的failbit.

您可以通过在执行读取操作后检查整数的failbit和值来检测这些溢出错误,如在istream中读取int的问题的已接受答案中所述,检测溢出.

您可以通过取消设置failbit 来从这些错误中恢复std::basic_ios::clear.在调用clearfailset失败后,进一步读取将按预期运行.

推荐阅读
jerry613
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有