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