C++ istream_迭代器从流中消耗太多

C++ istream_迭代器从流中消耗太多,c++,c++11,istream-iterator,C++,C++11,Istream Iterator,我从stdin获得以下输入: 2 5 2 1 5 3 4 5 2 5 1 3 4 第一行表示队列的数量(我们称这个值为n)。然后,对于每个队列,在第一行有一个值l,表示队列的长度,后面是实际队列 我试图使用istream\u迭代器将队列放入向量中,如下所示: using namespace std; int n{}; int l{}; typedef std::istream_iterator<int> input_iterator; cin >> n; cout<

我从stdin获得以下输入:

2
5
2 1 5 3 4
5
2 5 1 3 4
第一行表示队列的数量(我们称这个值为
n
)。然后,对于每个队列,在第一行有一个值
l
,表示队列的长度,后面是实际队列

我试图使用
istream\u迭代器将队列放入向量中,如下所示:

using namespace std;
int n{};
int l{};
typedef std::istream_iterator<int> input_iterator;
cin >> n;
cout<< "n: " << n << "\n";
for(int i = 0; i < n ; ++i){

    cin >> l;
    cout << "l: " << l << "\n";
    std::vector<int> queue;
    int counter = 0;
    for (input_iterator it(cin); counter < l && it != input_iterator(); ++it){
        queue.push_back((*it));
        ++counter;
    }
    cout<< "Queue: ";
    std::copy(queue.begin(), queue.end(), 
                  std::ostream_iterator<int>(std::cout, " "));
    cout << "\n";
}
如您所见,第一个队列已正确读取。但是第二个
l
应该是
5
,而不是
2


5
发生了什么变化?它是否被迭代器使用?我在哪里出错了?

i所有,但据我所知,istream迭代器允许在其
操作符++()
中提前阅读。因为您正在为读取的每个组(数字行)创建一个istream迭代器,所以您将丢弃一个已经从输入流中读取下一个整数的迭代器


一种解决方案是只在for循环外创建一次输入迭代器,并在整个过程中使用它。

您的问题是for循环将
i
保留在队列最后一个元素旁边的位置。因此,当调用
操作符>
获取
l
的下一个值时,您的“读取步骤”太远了

为了避免此问题,您可以对所有读取操作使用相同的迭代器,并对其重命名以避免与外部循环中的变量
i
发生名称冲突,如下所示:

using namespace std;
int n{};
int l{};
typedef std::istream_iterator<int> input_iterator;
cin >> n;
cout<< "n: " << n << "\n";
input_iterator it(cin);
for(int i = 0; i < n ; ++i){

    l = *(it++);
    cout << "l: " << l << "\n";
    std::vector<int> queue;
    int counter = 0;
    while( counter < l && it != input_iterator() ){
        queue.push_back(*(it++));
        ++counter;
    }
    cout<< "Queue: ";
    std::copy(queue.begin(), queue.end(), 
                  std::ostream_iterator<int>(std::cout, " "));
    cout << "\n";
}
使用名称空间std;
int n{};
int l{};
typedef std::istream_迭代器输入迭代器;
cin>>n;

coutA
for
循环基本上只是一个花哨的
while
循环

让我们从您的代码中获取此
for
循环:

for (input_iterator it(cin); counter < l && it != input_iterator(); ++i){
    queue.push_back((*it));
    ++counter;
}
for(输入迭代器it(cin);计数器
它相当于以下内容:

{
    input_iterator it(cin);
    while (counter < l && it != input_iterator())
    {
        queue.push_back((*it));
        ++counter;
        ++it;
    }
}
{
输入迭代器it(cin);
while(计数器
注意循环中的最后一行,
++it语句?这就是造成你问题的原因。它将增加迭代器一次,因此循环后迭代器已读取输入中的
5
。循环之后的下一个输入操作将读取下一行中的
2

一种解决方案是保留迭代器,并在外部循环中重用它。也许对所有输入都使用它


我在评论中暗示的另一个解决方案是,让
for
只从零循环到
l
,而不使用迭代器,只使用普通的
cin>…

在调试器中逐行遍历代码。停止隐藏变量,在内部循环中为迭代器使用另一个名称。另外,除了使用简单的
std::cin>>…
获取值的普通循环之外,还有什么原因需要使用输入迭代器吗?这和整个阴影问题实际上是编写此示例时发生的一个错误。我修好了
{
    input_iterator it(cin);
    while (counter < l && it != input_iterator())
    {
        queue.push_back((*it));
        ++counter;
        ++it;
    }
}