Шаг 104.
Библиотека STL.
Итераторные адаптеры. Потоковые итераторы

    На этом шаге мы рассмотрим использование потоковых итераторов.

    Потоковые адаптеры составляют еще одну чрезвычайно полезную разновидность итераторпых адаптеров. Под этим термином понимаются итераторы, обеспечивающие чтение из потока данных и запись в поток данных. Иначе говоря, потоковые итераторы позволяют интерпретировать ввод с клавиатуры как коллекцию, из которой можно читать данные. Аналогично, вы можете перенаправить результаты работы алгоритма в файл или на экран.

    Рассмотрим типичный пример, убедительно подтверждающий возможности STL. По сравнению с "чистой" реализацией С или C++ эта программа выполняет довольно большой объем работы всего в нескольких командах:

//---------------------------------------------------------------------------

#include <vcl.h>
#include <iostream>
#include <iterator>
#include <vector>
#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[])
{
  vector<string> coll;

  // Загрузка слов из стандартного входного потока данных
  // - источник: все строки до конца файла (или до возникновения ошибки)
  // - приемник: coll (вставка)
  cout << ToRus("Задайте слова (выход - CTRL+Z):\n");
  copy (istream_iterator <string> (cin),  // Начало источника
       istream_iterator <string> (),    // Конец источника
       back_inserter(coll));        //Приемник

  // Сортировка элементов
  sort (coll.begin(),coll.end());

  // Вывод всех элементов без дубликатов
  // - источник: coll
  // - приемник: стандартный вывод (с разделением элементов
  // символом новой строки)

  cout << ToRus("Отсортированные слова:\n");
  unique_copy (coll.begin(), coll.end(), // Источник
    ostream_iterator<string>(cout,"\n")); // Приемник

  cout << endl;

  getch();
  return 0;
}
//---------------------------------------------------------------------------
Текст этого примера можно взять здесь.

    Программа, фактически состоящая всего из трех команд, читает все слова из стандартного входного потока данных и выводит их в отсортированном виде (рисунок 1).


Рис.1. Результат работы приложения

    Давайте последовательно рассмотрим каждую из этих трех команд. В первой команде используются два потоковых итератора ввода:

  copy (istream_iterator <string> (cin),  // Начало источника
       istream_iterator <string> (),    // Конец источника
       back_inserter(coll));        //Приемник

    Подведем итог: источником данных для алгоритма сору() являются "все слова из cin". Прочитанные слова копируются в coll конечным итератором вставки.

    Алгоритм sort() сортирует все содержимое коллекции:

  sort (coll.begin(),coll.end());

    Наконец, следующая команда копирует все элементы коллекции в приемник cout:

  unique_copy (coll.begin(), coll.end(), // Источник
    ostream_iterator<string>(cout,"\n")); // Приемник

    В процессе копирования алгоритм unique_copy исключает из копируемых данных дубликаты. Представленное ниже выражение создает потоковый итератор вывода, который записывает string в выходной поток данных cout, вызывая оператор << для каждого элемента:

    ostream_iterator<string>(cout,"\n")); // Приемник

    Второй аргумент определяет разделитель, выводимый между элементами. Передавать этот аргумент не обязательно. В нашем примере разделителем является символ новой строки, поэтому каждый элемент будет выводиться в отдельной строке.

    Все компоненты программы реализованы в виде шаблонов, поэтому программа легко адаптируется для сортировки других типов данных (например, целых чисел или более сложных объектов).

    На следующем шаге мы рассмотрим обратные итераторы.




Предыдущий шаг Содержание Следующий шаг