简体   繁体   中英

simple istream_iterator question

I am new to C++, sorry if this is a silly question. 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). 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. Then enter "6 7 8 9 10 ctrl+d" into the console and have 6,7,8,9,10 entered into the second vector.

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. This causes every subsequent call to "copy" to fail (because istream_iteratorcin is already equal to istream_iterator() which the program interprets as eof). So my question is: What do I need to do to "reset" the iterator along with the cin stream? cin.clear() is indeed clearing all the fail bits. However the istream_iterator(cin) is still equal to istream_iterator() regardless. 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. What am I missing?

The istream_iterator is an input iterator , which means you can only dereference each iterator value once . 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); to make a copy?


Update: After you clarified the question, here's a new answer: You're misunderstanding how stdin works. There is only one input. Ctrl-D isn't anything inherent to C++; rather, it is a convention of your platform, and your platform will terminate the input buffer when you signal 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. 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 */ }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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