简体   繁体   English

简单的istream_iterator问题

[英]simple istream_iterator question

I am new to C++, sorry if this is a silly question. 我是C ++的新手,如果这是一个愚蠢的问题,对不起。 I cannot seem to figure out why this does not work. 我似乎无法弄清楚为什么这行不通。 It copies into the first vector, and seems to skip past the second copy call. 它复制到第一个向量中,并且似乎跳过了第二个复制调用。

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

I want to use the copy function to read istream_iterator input into any number of vectors(one call to copy per vector). 我想使用复制功能将istream_iterator输入读入任意数量的向量中(每个向量调用一次复制)。 In other words: I want to be able to enter "1 2 3 4 5 ctrl+d" into the console and have 1,2,3,4,5 entered into the first vector. 换句话说:我希望能够在控制台中输入“ 1 2 3 4 5 ctrl + d”,并在第一个向量中输入1,2,3,4,5。 Then enter "6 7 8 9 10 ctrl+d" into the console and have 6,7,8,9,10 entered into the second vector. 然后在控制台中输入“ 6 7 8 9 9 ctrl + d”,并将6,7,8,9,10输入第二个向量。

The problem is that after I enter some input into the first vector and press control+d the istream_iterator for cin remains equal to istream_iterator(), regardless of cin's fail state. 问题是,在我将一些输入输入到第一个向量中并按下Ctrl + d之后,cin的istream_iterator保持等于istream_iterator(),而与cin的失败状态无关。 This causes every subsequent call to "copy" to fail (because istream_iteratorcin is already equal to istream_iterator() which the program interprets as eof). 这将导致随后的所有对“ copy”的调用均失败(因为istream_iteratorcin已等于程序解释为eof的istream_iterator())。 So my question is: What do I need to do to "reset" the iterator along with the cin stream? 所以我的问题是:我需要做些什么来与cin流一起“重置”迭代器? cin.clear() is indeed clearing all the fail bits. cin.clear()确实清除了所有失败位。 However the istream_iterator(cin) is still equal to istream_iterator() regardless. 但是无论如何,istream_iterator(cin)仍等于istream_iterator()。 From what I understand, istream_iterators that are bound to a stream should only be equal to the default istream_iterator value when the stream is in a fail state. 据我了解,绑定到流的istream_iterators仅应在流处于故障状态时等于默认的istream_iterator值。 What am I missing? 我想念什么?

The istream_iterator is an input iterator , which means you can only dereference each iterator value once . istream_iterator是一个输入迭代器 ,这意味着您只能取消对每个迭代器值的引用一次 You are literally reading from a stream, and there's no seeking or going back. 您从字面上看是从流中读取的,没有寻找或返回的机会。 So once you hit the end-of-stream, there's nothing more to input and the second range is empty. 因此,一旦您到达了流的末端,就没有更多可输入的内容了,第二个范围为空。

Why not just say vector<int> second(first); 为什么不只说vector<int> second(first); to make a copy? 复制?


Update: After you clarified the question, here's a new answer: You're misunderstanding how stdin works. 更新:在澄清了问题之后,这是一个新答案:您误解了stdin工作原理。 There is only one input. 只有一个输入。 Ctrl-D isn't anything inherent to C++; Ctrl-D并不是C ++固有的东西。 rather, it is a convention of your platform, and your platform will terminate the input buffer when you signal Ctrl-D . 相反,这是您平台的惯例,并且您在发出Ctrl-D信号时,平台将终止输入缓冲区。 After that, the input "file" is finished, and no further data can be written to it. 此后,输入“文件”完成,无法再写入任何数据。

Your approach is a bit unorthodox, though. 但是,您的方法有点不合常规。 Usually, you would just read line by line, separated by Enter , and tokenize each line. 通常,您只需要逐行阅读,并用Enter分隔,并标记每行。 Using string streams, you get very similar code: 使用字符串流,您将获得非常相似的代码:

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 */ }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM