Чтение онлайн

на главную - закладки

Жанры

C++. Сборник рецептов

Когсуэлл Джефф

Шрифт:

В примере 7.11 показаны три ключевые части

istream_iterator
. Первая часть — это создание
istream_iterator
, указывающего на начало потокового ввода. Это делается вот так.

istream_iterator<string> start(cin);

В результате создается итератор с именем

start
, который указывает на первый элемент входной последовательности, точно так же, как
vec.begin
(
vec
— это
vector
) возвращает итератор, который указывает на первый элемент в векторе. Аргумент шаблона
string
говорит
istream_iterator
, что элементы в этой последовательности имеют тип
string
. Аргумент конструктора
cin
— это входной поток, из которого производится чтение. Однако это абстракция, так как первого элемента не существует, поскольку из
cin
еще ничего прочитано не было. Это произойдет несколько позже.

Вторая часть итератора входного потока — это маркер конца, который создается вот так.

istream_iterator<string> end;

Стандартные контейнеры используют специальное значение «один после конца», указывающее на точку, где должно остановиться использование алгоритма. Так как итератор входного потока не имеет в памяти последнего элемента, он для создания логической конечной точки, представляющей точку остановки использования алгоритма, использует конструктор без аргументов.

Последней частью методики использования

istream_iterator
является его использование для извлечения значений. Удобным способом вытащить в контейнер все значения, введенные в поток, является использование конструктора диапазона контейнера. Например, если создать
vector
с двумя итераторами, то его конструктор скопирует в контейнер все элементы диапазона, определяемого итераторами. Если передать только что созданные итераторы
start
и
end
, то это будет выглядеть так.

vector<string> v(start, end);

Именно здесь происходит чтение значений из потока. При создании

v
он начинает со
start
и перебирает все значения, пока не достигнет
end
. Каждый раз, когда
v
читает из
*start
, происходит нечто эквивалентное такому вызову
cin
.

cin >> v[i]; // v - это vector<string>

Другими словами, следующее значение, извлекаемое из

cin
, преобразуется в
string
и вставляется в
vector
.

При использовании
cin
как входного потока маркер конца файла, который отмечает конец потока, определяется используемой платформой. В Windows для завершения входного потока требуется нажать на Enter, Ctrl-Z, Enter. Чтобы увидеть, что требуется сделать на вашей платформе, проведите эксперименты, но велика вероятность, что будут использоваться эти же клавиши.

Итераторы выходных потоков ведут себя аналогично итераторам потоков ввода. В примере 7.11 я копирую значения из своего

vector
в
cout
, создав для этого
ostream_iterator
, который указывает на
cout
, следующим образом.

copy(v.begin, v.end, ostream_iterator<string>(cout, ", "));

Аргумент

шаблона
ostream_iterator
говорит, что записываемые элементы будут иметь тип
string
. Первый аргумент конструктора
ostream_iterator
— это поток, в который будет производиться запись (и который может быть любым потоком вывода, включая
ofstream
и
ostringstream
), а второй это используемый разделитель. Это дает удобный способ выводить диапазон значений на стандартный вывод, что я часто делаю при отладке.

Если требуется дополнительное управление внешним видом вывода, например вывод последовательности в квадратных или фигурных скобках или отсутствие последнего разделителя в конце последовательности, то это потребует всего нескольких дополнительных строк кода. Пример 7.12 показывает тело

printContainer
и
printRange
, первая из которых используется в примерах этой главы.

Пример 7.12. Написание собственной функции печати

#include <iostream>

#include <string>

#include <algorithm>

#include <iterator>

#include <vector>

using namespace std;

template<typename C>

void printContainer(const C& c, char delim = ',', ostream& out = cout) {

 printRange(c.begin, c.end, delim, out);

}

template<typename Fwd>

void printRange(Fwd first, Fwd last, char delim = ',', ostream& out = cout) {

 out << "{";

 while (first != last) {

out << *first;

if (++first != last)

out << delim << ' ';

 }

 out << "}" << endl;

}

int main {

 cout << "Введите набор строк: ";

 istream_iterator<string> start(cin);

 istream_iterator<string> end;

 vector<string> v(start, end);

 printContainer(v);

 printRange(v.begin, v.end, ';', cout);

}

Функция

printRange
представляет собой более общий подход, так как оперирует с диапазонами (более подробно это объясняется в рецепте 7.10), но
printContainer
более удобна для печати целого контейнера. Имеется множество других способов сделать это. В голову также приходит определение версии
operator<<
, которая бы работала с выходным потоком и контейнером, и использование стандартного алгоритма
for_each
с собственным функтором для записи элементов в поток.

Поделиться:
Популярные книги

Имя нам Легион. Том 2

Дорничев Дмитрий
2. Меж двух миров
Фантастика:
боевая фантастика
рпг
аниме
5.00
рейтинг книги
Имя нам Легион. Том 2

Где властвует любовь

Куин Джулия
4. Бриджертоны
Любовные романы:
исторические любовные романы
8.94
рейтинг книги
Где властвует любовь

Враг из прошлого тысячелетия

Еслер Андрей
4. Соприкосновение миров
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Враг из прошлого тысячелетия

Тепла хватит на всех

Котов Сергей
1. Миры Пентакля
Фантастика:
боевая фантастика
космическая фантастика
5.00
рейтинг книги
Тепла хватит на всех

Каторжник

Шимохин Дмитрий
1. Подкидыш
Фантастика:
попаданцы
альтернативная история
фэнтези
5.00
рейтинг книги
Каторжник

Жатва душ. Остров мертвых

Сугралинов Данияр
Фантастика:
боевая фантастика
рпг
5.20
рейтинг книги
Жатва душ. Остров мертвых

Старшеклассник без клана. Апелляция кибер аутсайдера

Афанасьев Семен
1. Старшеклассник без клана. Апелляция аутсайдера
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Старшеклассник без клана. Апелляция кибер аутсайдера

Черный маг императора 3

Герда Александр
3. Черный маг императора
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Черный маг императора 3

Изгой Проклятого Клана

Пламенев Владимир
1. Изгой
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Изгой Проклятого Клана

Ваше Сиятельство

Моури Эрли
1. Ваше Сиятельство
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Ваше Сиятельство

Солнечный корт

Сакавич Нора
4. Все ради игры
Фантастика:
зарубежная фантастика
5.00
рейтинг книги
Солнечный корт

Черный Маг Императора 4

Герда Александр
4. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Черный Маг Императора 4

Черный Маг Императора 9

Герда Александр
9. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Черный Маг Императора 9

Младший сын князя. Том 10

Ткачев Андрей Юрьевич
10. Аналитик
Фантастика:
городское фэнтези
аниме
сказочная фантастика
фэнтези
фантастика: прочее
5.00
рейтинг книги
Младший сын князя. Том 10