我从文本文件中提取数字并用它们填充int类型的数组.
我正在将值插入到数组中,同时使用这些代码行循环遍历.txt文件(其中k是.txt文件中的数字量):
for (int j = 0; j < k; j++) inputFile >> tab[j];
当文本文件中的数字小于2,147,483,647时,这是整数类型的最大大小,一切顺利.
当数字大于这个程序时,我假设溢出并且无法插入它,但它之后也无法插入任何数字.
导致溢出发生后不再插入数字的原因是什么?
该标准要求如果输入值超出范围,则将最近的可用值写入目标,并设置流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,它就会"粘滞",所以进一步尝试提取数据都将立即失败,直到故障清除被清除.
在std::istream& std::istream::operator>>(std::istream&, int&)
,cppreference说:
表现为FormattedInputFunction.在构造和检查可能跳过前导空格的sentry对象之后,通过调用提取整数值
std::num_get::get()
...
如果提取失败,则将零写入值并设置failbit.如果提取导致值太大或太小而无法拟合值,
std::numeric_limits
或者::max() std::numeric_limits
被写入并且设置了failbit标志.(自c ++ 11起)::min()
它不是规范性的,但它确实提供了对这里发生的事情的一个很好的总结.
FormattedInputFunctions将从流构造一个哨兵并检查该值.如果sentry对象的计算结果为false
,则不执行任何输入.
对于正在操作的流具有false
故障点设置,在其他情况下,哨兵对象将进行评估.
那么,发生了什么:
流尝试读入一个太大而不能保存在int
数据类型中的整数.
将int
传递到它的功能设置为最大可能值int
可以存储.
传递给函数的流具有其failbit集.
对流的进一步读取失败并且不执行任何操作,因为已设置流的failbit.
您可以通过在执行读取操作后检查整数的failbit和值来检测这些溢出错误,如在istream中读取int的问题的已接受答案中所述,检测溢出.
您可以通过取消设置failbit 来从这些错误中恢复std::basic_ios::clear
.在调用clear
failset失败后,进一步读取将按预期运行.