What happens when >> operator is trying to input a value bigger than a variable can contain?

大兔子大兔子 提交于 2020-05-09 04:33:30

问题


I'm pulling numbers from a text file and filling an array of type int with them.

I'm inserting the values into the array while looping through the .txt file with those lines of code (where k is the amount of numbers in the .txt file):

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

When the numbers in the text file are less than 2,147,483,647 which is the maximum size of an integer type everything goes smooth.

When the number is bigger than this the program as i assume overflows and fails to insert it but it also fails to insert any number after that.

What is causing it to not insert any more numbers after the overflow happens?


回答1:


On std::istream& std::istream::operator>>(std::istream&, int&), cppreference says:

Behaves as a FormattedInputFunction. After constructing and checking the sentry object, which may skip leading whitespace, extracts an integer value by calling std::num_get::get()

...

If extraction fails, zero is written to value and failbit is set. If extraction results in the value too large or too small to fit in value, std::numeric_limits<T>::max() or std::numeric_limits<T>::min() is written and failbit flag is set. (since c++11)

It's not normative, but it does provide a decent summary of what is happening here.

FormattedInputFunctions will construct a sentry from the stream and check the value. If the sentry object evaluates as false, then no input is performed.

The sentry object will evaluate as false if, among other situations, the stream being operated on has the failbit set.


So, what's happening is this:

  1. The stream tries to read in an integer too large to hold in the int data type.
  2. The int passed into its function is set to the maximum possible value an int can store.
  3. The stream passed into the function has its failbit set.
  4. Further reads to the stream fail and do nothing, because the stream's failbit is set.

You can detect these overflow errors by checking the failbit and value of the integer after the read operation you are performing, as mentioned in the accepted answer to the question Read int from istream, detect overflow.

You can recover from these errors by unsetting the failbit with std::basic_ios::clear. Following a call to clear which unsets the failbit, further reads will behave as you expect.




回答2:


The standard requires that if the input value is out of range, the nearest available value is written to the destination, and the stream's failbit is set. The specific requirement (from [istream.formatted.arithmetic]/3) is:

operator>>(int& val);

The conversion occurs as if performed by the following code fragment [...]:

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);

Once the stream's failbit is set, it's "sticky", so further attempts at extracting data will all fail immediately until the failbit is cleared.




回答3:


Undefined behaviour. Arithmetical overflow may be silently ignored or may cause a signal to be raised which terminates the program, depending on quality of implementation.



来源:https://stackoverflow.com/questions/41622680/what-happens-when-operator-is-trying-to-input-a-value-bigger-than-a-variable

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!