Программирование. Принципы и практика использования C++ Исправленное издание, стр. 299
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); // буфер копирования для вывода}Итератор
eosistreameofistream_iteratoristream_iteratoreos
(a,b)[a:b](ii,eos)>>push_back()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_iteratorostream_iterator<string> oo(os,"\n"); // создает итератор для // потока выводаОчевидно, что переход на новую строку — это распространенный выбор для вывода, позволяющий людям легче разбираться в результатах, но, возможно, вы предпочли бы использовать пробелы? Мы могли бы написать следующий код:
ostream_iterator<string> oo(os," "); // создает итератор для потока // выводаВ этом случае результаты вывода выглядели бы так:
bit dog man the
21.7.3. Использование класса set для поддержания порядка
Существует еще более простой способ получить такой вывод: использовать контейнер
setvectorint main(){ string from, to; cin >> from >> to; // имена исходного и целевого файлов ifstream is(from.c_str()); // создаем поток ввода ofstream os(to.c_str()); // создаем поток вывода istream_iterator<string> ii(is); // создаем итератор ввода