copy ( input, end_of_stream, inserter( vec, vec.begin() ));
sort( vec.begin(), vec.end(), greaterint() );
ostream_iterator int output( cout, " " );
unique_copy( vec.begin(), vec.end(), output );
}
unique_copy():
12.4.4. Итератор istream_iterator
В общем виде объявление потокового итератора чтения istream_iterator имеет форму
istream_iterator identifier( istream& );1.
Если имеющийся у Вас компилятор пока не поддерживает параметр шаблонов по умолчанию, то конструктору istream_iterator необходимо будет явно передать также и второй аргумент: тип difference_type, способный хранить результат вычитания двух итераторов контейнера, куда помещаются элементы. Например, в разделе 12.2 при изучении программы, которая должна транслироваться компилятором, не поддерживающим параметры шаблонов по умолчанию, мы писали:
typedef vector::difference_type diff_type
istream_iterator input_set1( infile1 ), eos;
istream_iterator input_set2( infile2 );
где Type – это любой встроенный или пользовательский тип класса, для которого определен оператор ввода. Аргументом конструктора может быть объект либо класса
#include iterator
#include fstream
#include string
#include complex
// прочитать последовательность объектов типа complex
// из стандартного ввода
istream_iterator complex is_complex( cin );
// прочитать последовательность строк из именованного файла
ifstream infile( "C++Primer" );
istream, например cin, либо производного от него класса с открытым типом наследования – ifstream:
istream_iterator string is_string( infile );
При каждом применении оператора инкремента к объекту типа istream_iterator читается следующий элемент из входного потока, для чего используется оператор operator(). Чтобы сделать то же самое в обобщенных алгоритмах, необходимо предоставить пару итераторов, обозначающих начальную и конечную позицию в файле.
// конструирует итератор end_of_stream, который будет служить маркером
// конца потока в итераторной паре
istream_iterator string end_of_stream
vectorstring text;
// правильно: передаем пару итераторов
copy( is_string, end_of_stream,
inserter( text, text.begin() ));
Начальную позицию дает istream_iterator, инициализированный объектом istream, – такой, скажем, как is_string. Для получения конечной позиции мы используем специальный конструктор по умолчанию класса istream_iterator.
12.4.5. Итератор ostream_iterator
Объявление потокового итератора записи ostream_iterator может быть представлено в двух формах:
Если бы компилятор полностью удовлетворял стандарту C++, достаточно было бы написать так:
istream_iterator input_set1( infile1 ), eos;
istream_iterator input_set2( infile2 );
ostream_iterator identifier( ostream& )
ostream_iterator identifier( ostream&, char * delimiter )
где Type – это любой встроенный или пользовательский тип класса, для которого определен оператор вывода (operator). Во второй форме delimiter – это разделитель, то есть C-строка символов, которая выводится в файл после каждого элемента. Такая строка должна заканчиваться двоичным нулем, иначе поведение программы не определено (скорее всего, она аварийно завершит выполнение). В качестве аргумента ostream может выступать объект класса ostream, например cout, либо
#include iterator
#include fstream
#include string
#include complex
// записать последовательность объектов типа complex
// в стандартный вывод, разделяя элементы пробелами
ostream_iterator complex os_complex( cin, " " );
// записать последовательность строк в именованный файл