2016-11-18 51 views
2

太多我从标准输入下列输入:istream_iterator消耗从流

2 
5 
2 1 5 3 4 
5 
2 5 1 3 4 

第一行代表队列数(我们称之为价值n)。然后,对于每个队列,在第一行中有一个值l,表示队列的长度,后面是实际的队列。

我试图用istream_iterator如下把队列中的向量:

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"; 
} 

此代码产生以下输出:

n: 2 
l: 5 
Queue: 2 1 5 3 4 
l: 2 
Queue: 5 1 

正如你所看到的第一个队列中读取正确。但第二个l应该是5,而不是2

发生了什么事5?它是否被迭代器使用?我在哪里犯了一个错误?

+0

在调试器中逐行执行代码。并停止阴影变量,在内部循环中为迭代器使用另一个名称。另外,是否有你想使用输入迭代器的原因,而不仅仅是一个简单的循环,你可以使用简单的'std :: cin >> ...'来获取值? –

+0

这和整个阴影事实上是写这个例子发生的错误。我修正了这一点 – user2393256

回答

2

您的问题是您的for-loop离开队列的最后一个元素旁边的位置i。所以当拨打operator>>获取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"; 
} 
2

IANALL,但istream_iterator据我所知允许在其operator++()中预读。由于您正在为读取的每个组(数组的行)重新创建一个istream迭代器,因此您将放弃已经从输入流中读取下一个整数的迭代器。

一个解决方案是在for循环之外创建输入迭代器一次,然后在整个循环中使用它。

2

一个for循环基本上只是一个花式的while循环。

让我们这个for循环从您的代码:

for (input_iterator it(cin); counter < l && it != input_iterator(); ++i){ 
    queue.push_back((*it)); 
    ++counter; 
} 

它等效于以下内容:

{ 
    input_iterator it(cin); 
    while (counter < l && it != input_iterator()) 
    { 
     queue.push_back((*it)); 
     ++counter; 
     ++it; 
    } 
} 

注意,在循环最后一行时,++it;说法? 这就是是什么导致你的问题。它会增加一次太多的迭代器,所以迭代器在循环之后读取输入中的5。循环之后的下一个输入操作将读取下一行中的2

一个解决方案是保持迭代器,并在外部循环中重用它。也许使用它为全部输入。

另一种解决方案,这是我暗示关于我的评论,是有从零到lfor仅环而不是在所有使用迭代器,但只有纯cin >> ...