简单的istream_iterator问题

时间:2011-09-15 18:32:55

标签: c++ copy istream-iterator

我是C ++的新手,对不起,如果这是一个愚蠢的问题。我似乎无法弄清楚为什么这不起作用。它复制到第一个向量中,似乎跳过第二个复制调用。

#include <iostream>
#include <vector>
#include <iterator>

using namespace std;

int main ()
{
    vector<int> first;
    vector<int> second;

    copy(istream_iterator<int>(cin),istream_iterator<int>(),back_inserter(first));
    cin.clear();
    copy(istream_iterator<int>(cin),istream_iterator<int>(),back_inserter(second)); 
    return 0;
}

我想使用copy函数将istream_iterator输入读入任意数量的向量(每个向量一次调用复制)。换句话说:我希望能够在控制台中输入“1 2 3 4 5 ctrl + d”并将1,2,3,4,5输入到第一个矢量中。然后在控制台中输入“6 7 8 9 10 ctrl + d”并将6,7,8,9,10输入到第二个矢量中。

问题是,在我输入第一个向量中的一些输入并按下control + d后,无论cin的失败状态如何,cin的istream_iterator仍然等于istream_iterator()。这导致每次后续调用“复制”失败(因为istream_iteratorcin已经等于istream_iterator(),程序将其解释为eof)。 所以我的问题是:我需要做什么才能“重置”迭代器和cin流? cin.clear()确实清除了所有的失败位。但是,istream_iterator(cin)仍然等于istream_iterator()。根据我的理解,当流处于失败状态时,绑定到流的istream_iterator应该只等于默认的istream_iterator值。我错过了什么?

1 个答案:

答案 0 :(得分:1)

istream_iterator输入迭代器,这意味着您只能取消引用每个迭代器值一次。你实际上是从一个流中读取,而且没有寻求或回头。所以一旦你点到了流的末尾,没有什么可以输入的,第二个范围是空的。

为什么不直接说vector<int> second(first);来制作副本?


更新:在您澄清问题后,这是一个新答案:您误解了stdin的工作原理。只有一个输入。 Ctrl-D不是C ++固有的东西;相反,它是您平台的惯例,当您发出Ctrl-D信号时,您的平台将终止输入缓冲区。之后,输入“文件”结束,不能再向其写入数据。

但你的方法有点不正统。通常,您只需逐行读取,以Enter分隔,并对每一行进行标记。使用字符串流,您将得到非常相似的代码:

std::string line;
std::vector<int> first, second;

// Read line 1
if (std::getline(std::cin, line))
{
  std::istringstream iss(line);
  std::copy(std::istream_iterator<int>(iss), std::istream_iterator<int>(), std::back_inserter(first));
}
else { /* error */ }

// Read line 2
if (std::getline(std::cin, line))
{
  std::istringstream iss(line);
  std::copy(std::istream_iterator<int>(iss), std::istream_iterator<int>(), std::back_inserter(second));
}
else { /* error */ }