问题描述
我正在通过检查/编写不同的示例来学习迭代器。在一个这样的例子中(下面给出),当我在输入流中输入一个无效类型说 char
时,下一个 cout
语句不会被执行。示例如下:
#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;
}
现在当我执行这个程序并输入值时说 1 2 f
然后按回车键,然后控制台上只打印两个“之后”。 我的问题是为什么“after”没有在屏幕上打印 3 次?
这就是我认为正在发生的事情:
第 1 步。因为一开始 starting_it
和 ending_it
不相等,所以我们进入 while 循环。
第 2 步。现在,starting_it
递增,同时从 cin
中读取一个值。
第 3 步。接下来,返回 starting_it
的旧值,我们对其应用 *
运算符。这在当前迭代中具有值 1,它在语句结束时被丢弃。下一个 cout<<"after"<<std::endl;
被执行并打印在控制台上。
第 4 步。现在再一次,因为我们没有遇到文件结束或任何输入错误,所以我们进入 while 循环的下一次迭代。
步骤 5。重复步骤 1-步骤 4。这次唯一的区别是,在 Step4 结束时,当我们取消引用 starting_it
时,我们得到了值 2。
第六步。现在我们再次进入下一次迭代。但是这次当 starting_it
递增时,读取的字符类型无效,因此 starting_it
等于结束迭代器。
现在我的问题是在该步骤中应该执行语句std::cout<<"after"<<std::endl
,并且应该在控制台上打印“after”。然后应该检查 while 的条件。出来是假的。但为什么这没有发生呢?为什么我们在控制台上只打印了两个“after”而不是 3 个。是不是因为 ostream 也出错了。实际上,似乎每当我们在输入流上遇到错误或 eof 时,我们就会跳出 while 循环。另外,我的解释是否正确,如果不正确,请纠正我。
我附上了输出的截图。
解决方法
std::istream_iterator
预读:构造函数中的第一次读取,operator++
中的后续读取。 operator*
返回先前读取的缓存值。如果任何读取失败,迭代器就等于结束迭代器。
这就是您的示例中发生的情况。 starting_it
在构造函数中读取 1
。循环的第一次迭代读取 2
并打印第一个 after
。循环的第二次迭代尝试读取 f
(此时 starting_it
变为等于 ending_it
)并打印第二个 after
。那么循环存在。
总共执行了三个读取 - 一个在构造函数中,两个在两个 operator++
调用中,对应于打印了两次 after
。