простой вопрос istream_iterator - PullRequest
       16

простой вопрос istream_iterator

1 голос
/ 15 сентября 2011

Я новичок в 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;
}

Я хочу использовать функцию копирования для чтения ввода 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, istream_iterator для cin остается равным istream_iterator (), независимо от состояния сбоя cin.Это приводит к сбою при каждом последующем вызове «copy» (потому что istream_iteratorcin уже равен istream_iterator (), который программа интерпретирует как eof).Итак, мой вопрос: что мне нужно сделать, чтобы «сбросить» итератор вместе с потоком cin?cin.clear () действительно очищает все биты сбоя.Однако istream_iterator (cin) все равно равен istream_iterator () независимо.Из того, что я понимаю, istream_iterators, которые связаны с потоком, должны быть равны значению istream_iterator по умолчанию, только когда поток находится в состоянии сбоя.Чего мне не хватает?

1 Ответ

1 голос
/ 15 сентября 2011

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 */ }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...