Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп
Книгу Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп читаем онлайн бесплатно полную версию! Чтобы начать читать не надо регистрации. Напомним, что читать онлайн вы можете не только на компьютере, но и на андроид (Android), iPhone и iPad. Приятного чтения!
Шрифт:
Интервал:
Закладка:
В стандартной библиотеке есть тип ostream_iterator, предназначенный для работы с потоком вывода; ostream_iterator<T> — это итератор, который можно использовать для записи значений типа T.
В стандартной библиотеке есть также тип istream_iterator<T> для чтения значений типа T.
istream_iterator<string> ii(cin); // чтение *ii — это чтение строки
// из cin
string s1 = *ii; // т.е. cin>>s1
++ii; // "готов к вводу следующего
// элемента"
string s2 = *ii; // т.е. cin>>s2
Используя итераторы ostream_iterator и istream_iterator, можно вводить и выводить данные с помощью алгоритма copy(). Например, словарь, сделанный наспех, можно сформировать следующим образом:
int main()
{
string from, to;
cin >> from >> to; // вводим имена исходного
// и целевого файлов
ifstream is(from.c_str()); // открываем поток ввода
ofstream os(to.c_str()); // открываем поток вывода
istream_iterator<string> ii(is); // создаем итератор ввода
// из потока
istream_iterator<string> eos; // сигнальная метка ввода
ostream_iterator<string> oo(os,"n"); // создаем итератор
// вывода в поток
vector<string> b(ii,eos); // b — вектор, который
// инициализируется
// данными из потока ввода
sort(b.begin(),b.end()); // сортировка буфера
copy(b.begin(),b.end(),oo); // буфер копирования для вывода
}
Итератор eos — это сигнальная метка, означающая “конец ввода.” Когда поток istream достигает конца ввода (который часто называется eof), его итератор istream_iterator становится равным итератору istream_iterator, который задается по умолчанию и называется eos.

vector<string> b(max_size); // не пытайтесь угадать объем входных
// данных
copy(ii,eos,b.begin());
Люди, пытающиеся угадать максимальный размер ввода, обычно недооценивают его, переполняют буфер и создают серьезные проблемы как для себя, так и для пользователей. Переполнение буфера может также создать опасность для сохранности данных.
ПОПРОБУЙТЕ
Приведите программу в рабочее состояние и протестируйте ее на небольшом файле, скажем, содержащем несколько сотен слов. Затем испытайте “настоятельно не рекомендованную версию”, в которой объем входных данных угадывается, и посмотрите, что произойдет при переполнении буфера ввода b. Обратите внимание на то, что наихудшим сценарием является тот, в котором вы не замечаете ничего плохого и передаете программу пользователям.
В нашей маленькой программе мы считываем слова, а затем упорядочиваем их. Пока все, что мы делаем, кажется очевидным, но почему мы записываем слова в “неправильные” ячейки, так что потом вынуждены их сортировать? Кроме того, что еще хуже, оказывается, что мы записываем слова и выводим их на печать столько раз, сколько они появляются в потоке ввода.
Последнюю проблему можно решить, используя алгоритм unique_copy() вместо алгоритма copy(). Функция unique_copy() просто не копирует повторяющиеся идентичные значения. Например, при вызове обычной функции copy() программы введет строку
the man bit the dog
и выведет на экран слова
bit
dog
man
the
the
Если же используем алгоритм unique_copy(), то программа выведет следующие слова:
bit
dog
man
the

ostream_iterator<string> oo(os,"n"); // создает итератор для
// потока вывода
Очевидно, что переход на новую строку — это распространенный выбор для вывода, позволяющий людям легче разбираться в результатах, но, возможно, вы предпочли бы использовать пробелы? Мы могли бы написать следующий код:
ostream_iterator<string> oo(os," "); // создает итератор для потока
// вывода
В этом случае результаты вывода выглядели бы так:
bit dog man the
21.7.3. Использование класса set для поддержания порядка
Существует еще более простой способ получить такой вывод: использовать контейнер set, а не vector.
int main()
{
string from, to;
cin >> from >> to; // имена исходного и целевого файлов
ifstream is(from.c_str()); // создаем поток ввода
ofstream os(to.c_str()); // создаем поток вывода
istream_iterator<string> ii(is); // создаем итератор ввода
// из потока
istream_iterator<string> eos; // сигнальная метка для ввода
ostream_iterator<string> oo(os," "); // создаем итератор
// вывода в поток
set<string> b(ii,eos); // b — вектор, который инициализируется
// данными из потока ввода
copy(b.begin(),b.end(),oo); // копируем буфер в поток вывода
}

21.7.4. Алгоритм copy_if()
Алгоритм copy() выполняет копирование без каких-либо условий. Алгоритм unique_copy() отбрасывает повторяющиеся соседние элементы, имеющие одинаковые значения. Третий алгоритм копирует только элементы, для которых заданный предикат является истинным.
template<class In,class Out,class Pred>
Out copy_if(In first,In last,Out res,Pred p)
// копирует элементы, удовлетворяющие предикату
{
while (first!=last) {
if (p(*first)) *res++ = *first;
++first;
}
return res;
}
Используя наш объект-функцию Larger_than из раздела 21.4, можем найти все элементы последовательности, которые больше шести.
void f(const vector<int>& v)
// копируем все элементы, которые больше шести
{
vector<int> v2(v.size());
copy_if(v.begin(),v.end(),v2.begin(),Larger_than(6));
// ...
}

Прочитали книгу? Предлагаем вам поделится своим отзывом от прочитанного(прослушанного)! Ваш отзыв будет полезен читателям, которые еще только собираются познакомиться с произведением.
Уважаемые читатели, слушатели и просто посетители нашей библиотеки! Просим Вас придерживаться определенных правил при комментировании литературных произведений.
- 1. Просьба отказаться от дискриминационных высказываний. Мы защищаем право наших читателей свободно выражать свою точку зрения. Вместе с тем мы не терпим агрессии. На сайте запрещено оставлять комментарий, который содержит унизительные высказывания или призывы к насилию по отношению к отдельным лицам или группам людей на основании их расы, этнического происхождения, вероисповедания, недееспособности, пола, возраста, статуса ветерана, касты или сексуальной ориентации.
- 2. Просьба отказаться от оскорблений, угроз и запугиваний.
- 3. Просьба отказаться от нецензурной лексики.
- 4. Просьба вести себя максимально корректно как по отношению к авторам, так и по отношению к другим читателям и их комментариям.
Надеемся на Ваше понимание и благоразумие. С уважением, администратор knigkindom.ru.
Оставить комментарий
-
Гость Татьяна24 сентябрь 22:20 Как то не очень... Невеста по ошибке. Я не дам тебе развод - Майя Линн
-
Римма24 сентябрь 21:52 Почему главные героинитпкие идиотки? И сюжет не плохой, и написано хорошо. Но как героиня - так дура дурой.... Хозяйка маленького дома, или Любимая для дракона - Кира Рамис
-
Римма20 сентябрь 12:27 Много ненужных пояснений и отступлений. Весь сюжет теряет свою привлекательность. Героиня иногда так тупит, что читать не... Хозяйка приюта для перевертышей и полукровок - Елена Кутукова