На этом шаге мы рассмотрим еще одини пример использования потоковых итераторов.
В следующем примере задействованы обе разновидности потоковых итераторов, а также функция advance():
//--------------------------------------------------------------------------- #include <vcl.h> #include <iostream> #include <iterator> #include <string> #include <algorithm> #include <conio.h> //необходимо для getch() #pragma hdrstop //--------------------------------------------------------------------------- #pragma argsused using namespace std; std::string ToRus(const std::string &in) { char *buff = new char [in.length()+1]; CharToOem(in.c_str(),buff); std::string out(buff); delete [] buff; return out; } int main(int argc, char* argv[]) { istream_iterator<string> cinPos(cin); ostream_iterator<string> coutPos(cout," "); // Пока при вводе не будет достигнут конец файла // - записывать каждую третью строку cout << ToRus("\nРезультат:\n"); while (cinPos != istream_iterator<string>()) { // Пропустить следующие две строки advance (cinPos, 2); // Чтение и запись третьей строки if (cinPos != istream_iterator<string>()) { *coutPos++ = *cinPos++; } } getch(); return 0; } //---------------------------------------------------------------------------
Вспомогательная функция advance() перемещает итератор к другой позиции. При использовании с потоковыми итераторами вывода она позволяет пропускать лексемы во входном потоке данных. Пример входных данных и результат приведены на рисунке 1:
Рис.1. Результат работы приложения
Прежде чем обращаться к значению *cinPos после вызова advance(), не забудьте убедиться в том, что потоковый итератор вывода остался действительным. Вызов оператора * для итератора конца потока данных приводит к непредсказуемым последствиям.
На следующем шаге мы рассмотрим трактовку итераторов.