Совет 29. Рассмотрите возможность использования istreambuf_iterator при посимвольном вводе
Совет 29. Рассмотрите возможность использования istreambuf_iterator при посимвольном вводе
Предположим, вы хотите скопировать текстовый файл в объект string. На первый взгляд следующее решение выглядит вполне разумно:
ifstream inputFile("interestringData.txt");
string fileData(istream_iterator<char>(inputFile)), // Прочитать inputFile istream iterator<char>0);// в fileData
Но вскоре выясняется, что приведенный синтаксис не копирует в строку пропуски (whitespace), входящие в файл. Это объясняется тем, что isream_iterator производит непосредственное чтение функциями operator<<, а эти функции по умолчанию не читают пропуски.
Чтобы сохранить пропуски, входящие в файл, достаточно включить режим чтения пропусков сбросом флага skipws для входного потока:
ifstream inputFile("interestingData.txt"):
inputFle.unset(ios::skipws);// Включить режим
// чтения пропусков
// в inputFile
string fileData(istream_iterator<char>(inputFile)), // Прочитать inputFile istream_iterator<char>0);// в fileData.
Теперь все символы InputFile копируются в fileData.
Кроме того, может выясниться, что копирование происходит не так быстро, как вам хотелось бы. Функции operator<<, от которых зависит работа stream_iterator, производят форматный ввод, а это означает, что каждый вызов сопровождается многочисленными служебными операциями. Они должны создать и уничтожить объекты sentry (специальные объекты потоков ввода-вывода, выполняющие начальные и завершающие операции при каждом вызове operator<<); они должны проверить состояние флагов, влияющих на их работу (таких, как skpws); они должны выполнить доскональную проверку ошибок чтения, а в случае обнаружения каких-либо проблем — проанализировать маску исключений потока и определить, нужно ли инициировать исключение. Все перечисленные операции действительно важны при форматном вводе, но если ваши потребности ограничиваются чтением следующего символа из входного потока, без них можно обойтись.
Более эффективное решение основано на использовании неприметного итератора istreambuf_iterator. Итераторы istreambuf_iterator работают аналогично istream_iterator, но если объекты istream_iterator<char> читают отдельные символы из входного потока оператором <<, то объекты streambuf_iterator обращаются прямо к буферу потока и непосредственно читают следующий символ (выражаясь точнее, объект streambuf_iterator<char> читает следующий символ из входного потока s вызовом s.rdbuf ()->sgetc()).
Перейти на использование istreambuf_iiterator при чтении файла так просто, что даже программист Visual Basic сделает это со второй попытки:
ifstream inputFile("interestingData.txt");
string fileData(istreambuf_iterator<char>(inputFile)). istreambuf_iterator<char>0);
На этот раз сбрасывать флаг skpws не нужно, итераторы streambuf_iterator никогда не пропускают символы при вводе и просто возвращают следующий символ из буфера.
По сравнению с istream_iterator это происходит относительно быстро. В проведенных мною простейших тестах выигрыш по скорости достигал 40%, хотя в вашем случае цифры могут быть другими. Не удивляйтесь, если быстродействие будет расти со временем; итераторы istreambuf_iterator населяют один из заброшенных уголков STL, и авторы реализаций еще недостаточно позаботились об их оптимизации. Например, в моих примитивных тестах итераторы istreambuf_iterator одной из реализаций работали всего на 5% быстрее, чем istream_iterator. В таких реализациях остается широкий простор для оптимизации i streambuf_iterator.
Если вы планируете читать из потока по одному символу, не нуждаетесь в средствах форматирования ввода и следите за эффективностью выполняемых операций, три лишних символа на итератор — не такая уж дорогая цена за заметный рост быстродействия. При неформатном посимвольном вводе всегда рассматривайте возможность применения sreambuf_iterator.
Раз уж речь зашла о буферизованных итераторах, следует упомянуть и об использовании osreambuf_iterator при неформатном посимвольном выводе. По сравнению с ostream_iterator итераторы ostream_bufiterator обладают меньшими затратами (при меньших возможностях), поэтому обычно они превосходят их по эффективности.
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
B.1 Возможность получения документов RFC
B.1 Возможность получения документов RFC На момент выхода книги документы RFC можно было получить в службе каталогов и баз данных InterNIC (InterNIC Directory and Database Services), обслуживаемой компанией AT&T. Эта служба доступна по адресу:http://www.internic.net/при выборе DIRECTORY AND DATABASE SERVICES и перехода по
Правило 35: Рассмотрите альтернативы виртуальным функциям
Правило 35: Рассмотрите альтернативы виртуальным функциям Предположим, что вы работаете над видеоигрой и проектируете иерархию игровых персонажей. В вашей игре будут использоваться разные варианты сражений, персонажи могут подвергаться ранениям или иначе терять
Автозамена как средство предотвращения ошибок при вводе
Автозамена как средство предотвращения ошибок при вводе В данном разделе мы рассмотрим механизм автозамены, использование которого позволяет избежать случайных ошибок, возникающих при вводе тех либо иных данных (текстовых, в формате даты и др.). Его смысл заключается в
Совет 23. Рассмотрите возможность замены ассоциативных контейнеров сортированными векторами
Совет 23. Рассмотрите возможность замены ассоциативных контейнеров сортированными векторами Многие программисты STL, столкнувшись с необходимостью структуры данных с быстрым поиском, немедленно выбирают стандартные ассоциативные контейнеры set, multiset, map и multimap. В этом
Поиск величины при вводе
Поиск величины при вводе Каким способом можно производить поиск подходящих величин в момент ввода? Табличный курсор (визуально) должен перемещаться к наиболее подходящему значению при добавлении пользователем новых символов водимой величины.Первоначально код писался
Предупреждение дублирования записей при вводе их из формы
Предупреждение дублирования записей при вводе их из формы В главе 11 мы обсуждали вопрос об очистке базы данных от повторяющихся записей, которые попали в таблицы, и выяснили, что этот механизм может работать и в профилактическом режиме, предотвращая попадание дубликатов
18.7.2. Применение цикла while при вводе с клавиатуры
18.7.2. Применение цикла while при вводе с клавиатуры Цикл while может применяться для ввода информации с клавиатуры. В следующем примере введенная информация присваивается переменной film. Если нажать клавиши [Ctrl+D], цикл завершает выполнение.$ pg whileread#!/bin/sh# whilereadecho " type <CTRL?D> to
Возможность повторного использования
Возможность повторного использования После этого краткого вторжения в зону объектной территории вернемся к анализу метода сверху вниз и рассмотрим его на сей раз по отношению к одной из наших основных целей - возможности повторного использования ПО. При разработке
Возможность повторного использования
Возможность повторного использования Обсуждение возможности повторного использования показало, что процедура (элемент функциональной декомпозиции) обычно недостаточна как единица для повторного использования. Мы рассмотрели ранее (лекция 4) типичный пример: поиск в
Поломки при вводе
Поломки при вводе Предположим, что в интерактивной системе необходимо выдать подсказку пользователю, от которого требуется ввести целое. Пусть только одна процедура занимается вводом целых - read_one_integer, которая результат ввода присваивает атрибуту last_integer_read. Эта
Возможность наблюдения и слежки
Возможность наблюдения и слежки Интересно взглянуть на вопрос о сетевой видимости с точки зрения прозрачности узлов и каналов, связывающих узлы. Прозрачный — значит видимый для посторонних, возможно для сил правопорядка или разведки. Непрозрачный — значит
6 О вводе
6 О вводе ОДНО ИЗ ГЛАВНЫХ ПРЕИМУЩЕСТВ Интернета заключается в том, что он позволяет человеку не только изучать и использовать контент, но и участвовать в его создании. В мобильных технологиях правильная организация ввода данных — вопрос не менее важный, чем их
Голубятня: Об Алёне из Эволвы и пальцевом вводе косинуса Сергей Голубицкий
Голубятня: Об Алёне из Эволвы и пальцевом вводе косинуса Сергей Голубицкий Опубликовано 05 февраля 2013 года В минувшую пятницу так увлекся музыкальными эмоциями, что напрочь забыл подвести итоги нашей викторины и поздравить победителей :) Сегодня
Об Алёне из Эволвы и пальцевом вводе косинуса Сергей Голубицкий
Об Алёне из Эволвы и пальцевом вводе косинуса Сергей Голубицкий Опубликовано 05 февраля 2013 В минувшую пятницу так увлекся музыкальными эмоциями, что напрочь забыл подвести итоги нашей викторины и поздравить победителей :) Сегодня непременно