2017-01-12 23 views
4

我从文本文件中拉出数字并用它们填充int类型的数组。当>>运算符试图输入一个大于变量的值时,会发生什么情况?

我插入值到阵列,同时通过与这些代码行(其中,k是数字的.txt文件的量)的.txt文件循环:

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

当数字在文本文件中小于2,147,483,647这是一个整数类型的最大尺寸一切顺利。

当这个数字大于这个数字时,我假定程序溢出并且未能插入它,但是它之后也没有插入任何数字。

什么导致它不会在溢出发生后再插入更多数字?

+8

溢出操作是设置流中的故障位,因为它应该在读取失败后执行。进一步的读取操作将不执行任何操作,直到失败位被清除。 – jaggedSpire

回答

5

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

表现为FormattedInputFunction。构建和检查岗哨对象,它可以跳过前导空白后,通过调用std::num_get::get()

...

如果提取失败提取的整数值,零写入重视和failbit设置。如果提取的结果值太大或太小而不适合值,则写入std::numeric_limits<T>::max()std::numeric_limits<T>::min(),并设置失败位标志。 (因为C++ 11)

这不是规范的,但它确实提供了这里发生了什么体面的摘要。

FormattedInputFunctions将从流中构造一个哨兵并检查该值。如果哨兵对象评估为false,则评估为no input is performed

哨兵对象将评估为false如果among other situations,正在操作的流具有故障位集。


所以,发生的事情是这样的:

  1. 流试图在一个整数太大,不能int数据类型来保存阅读。
  2. int传递到它的功能被设置为最大可能值的int可以存储。
  3. 传递给函数的流具有其失败位集。
  4. 进一步读取流失败并且什么都不做,因为流的失败位已设置。

您可以通过检查整数的failbit和价值正在执行的读操作之后,作为公认的答案中提到的问题Read int from istream, detect overflow检测这些溢出错误。

您可以通过取消设置std::basic_ios::clear的失败位从这些错误中恢复。在致电clear后,它将取消故障位,进一步读取将按照您的预期行事。

-5

未定义的行为。根据实施的质量,算术溢出可能会被默默忽略,或者可能导致终止程序的信号被提出。

+2

这完全不是。 [数字超出范围时,'operator >>(std :: istream&,int&)'的行为被显式指定](http://en.cppreference.com/w/cpp/io/basic_istream/operator_gtgt)可由int表示:实现将传递的int值设置为最接近的可表示值,然后在流上设置失败位。 – jaggedSpire

+1

实际上没有溢出。提取失败,并在流中设置失败,作为q sais的注释 – bolov

5

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

operator>>(int& val); 

的转换发生,如同通过下面的代码片断[...]进行:

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

一旦流的故障位被设置,它就是“粘滞”的,所以进一步尝试提取数据将立即失败,直到故障位被清除。

相关问题