i am learning about iterators by checking/writing different examples. In one such example(given below) when i enter an invalid type say char
into the input stream the next cout
statement is not executed. The example is as follows:
#include <iostream>
#include <iterator>
int main()
{
std::istream_iterator<int> starting_it(std::cin), ending_it;
while(starting_it != ending_it)
{
*starting_it++;//lets say i entered the character f on the console and pressed enter then why is the next cout statement not executed
std::cout<<"after"<<std::endl;//this line is not printed on the console after an invalid type is encountered
}
return 0;
}
Now when i execute this program and enter the values say 1 2 f
and then press enter, then only two "after" are printed on the console. My question is why isn't "after" printed 3 times on the screen?
This is what i think is happening:
Step 1. Since at the beginnnig starting_it
and ending_it
are not equal we go inside the while loop.
Step 2. Now, starting_it
is incremented and also at the same time a value is read from cin
.
Step 3. Next, the old value of starting_it
is returned on which we apply the *
operator. This in the current iteration has value 1 which is discarded at the end of the statement. Next cout<<"after"<<std::endl;
is executed and printed on the console.
Step 4. Now again since we have not encountered end of file or any input error so we go to the next iteration of the while loop.
Step 5. Step1-Step4 are repeated. The only difference this time is that at the end of Step4 when we dereference starting_it
we get the value 2.
Step6 . Now again we go into the next iteration. But this time when starting_it
is incremented, an invalid type of char is read and so starting_it
is made equal to the end iterator.
Now my question is that in the step the statementstd::cout<<"after"<<std::endl
should be executed and "after" should be printed on the console.And then the condition of while should be checked which comes out to be false. But why isn't this happening? Why do we have only two "after" printed on the console instead of 3. Is this because ostream is also in error. Effectively, it seems whenever we encounter an error or eof on input stream, we break out of the while loop. Also, is my explanation correct, if not then please correct me.
I have attached the screenshot of the output.
std::istream_iterator
reads ahead: the first read in constructor, subsequent reads in operator++
. operator*
returns the previously read, cached value. If any of the reads fail, the iterator becomes equal to the end iterator.
So this is what happens in your example. starting_it
reads 1
in constructor. The first iteration of the loop reads 2
and prints the first after
. The second iteration of the loop attempts to read f
(at which point starting_it
becomes equal to ending_it
) and prints the second after
. Then the loop exists.
All in all, three reads are executed - one in constructor, two in the two operator++
calls, corresponding to the two times after
is printed.