Д. Стефенс - C++. Сборник рецептов

Тут можно читать онлайн Д. Стефенс - C++. Сборник рецептов - бесплатно полную версию книги (целиком) без сокращений. Жанр: comp-programming, издательство КУДИЦ-ПРЕСС, год 2007. Здесь Вы можете читать полную версию (весь текст) онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.
  • Название:
    C++. Сборник рецептов
  • Автор:
  • Жанр:
  • Издательство:
    КУДИЦ-ПРЕСС
  • Год:
    2007
  • Город:
    Москва
  • ISBN:
    5-91136-030-6
  • Рейтинг:
    3.9/5. Голосов: 101
  • Избранное:
    Добавить в избранное
  • Отзывы:
  • Ваша оценка:
    • 80
    • 1
    • 2
    • 3
    • 4
    • 5

Д. Стефенс - C++. Сборник рецептов краткое содержание

C++. Сборник рецептов - описание и краткое содержание, автор Д. Стефенс, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru

Данная книга написана экспертами по C++ и содержит готовые рецепты решения каждодневных задач для программистов на С++. Один из авторов является создателем библиотеки Boost Iostreams и нескольких других библиотек C++ с открытым исходным кодом. В книге затрагивается множество тем, вот лишь некоторые из них: работа с датой и временем; потоковый ввод/вывод; обработка исключений; работа с классами и объектами; сборка приложений; синтаксический анализ XML-документов; программирование математических задач. Читатель сможет использовать готовые решения, а сэкономленное время и усилия направить на решение конкретных задач.

C++. Сборник рецептов - читать онлайн бесплатно полную версию (весь текст целиком)

C++. Сборник рецептов - читать книгу онлайн бесплатно, автор Д. Стефенс
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

std::reverse(s.begin(), s.end());

Обсуждение

reverseработает очень просто: она изменяет диапазон, переданный ей, так, что его порядок меняется на обратный оригинальному. Время, необходимое для этого, линейно зависит от длины диапазона.

В случае, если требуется скопировать строку в другую строку, но в обратном порядке символов, используйте реверсивные итераторы, как здесь:

std::string s = "Los Angeles";

std::string rs;

rs.assign(s.rbegin(), s.rend());

rbeginи rendвозвращают реверсивные итераторы. Реверсивные итераторы ведут себя так, как будто они просматривают последовательность в обратном порядке. rbeginвозвращает итератор, который указывает на последний элемент, a rendвозвращает итератор, указывающий на позицию перед первым элементом. Это в точности обратно тому, что делают beginи end.

Но должны ли вы обращать строку? С помощью rbeginи rendдля обратной строки можно использовать все методы или алгоритмы, работающие с диапазонами итераторов. А если требуется выполнить поиск в строке, то можно использовать rfind, которая делает то же, что и find, но начинает с конца строки и движется к ее началу. Для больших строк или большого количества строк обращение может оказаться очень дорогостоящим, так что при возможности избегайте его.

4.6. Разделение строки

Проблема

Требуется разделить строку с разделителями на несколько строк. Например, может потребоваться разделить строку "Name|Address|Phone"на три отдельных строки — "Name", "Address"и "Phone", удалив при этом разделитель.

Решение

Для перехода от одного вхождения разделителя к следующему используйте метод findкласса basic_string, а для копирования каждой подстроки используйте substr. Для хранения результатов используйте любую стандартную последовательность. Пример 4.10 использует vector.

Пример 4.10. Разделение строки с разделителями

#include

#include

#include

#include

using namespace std;

void split(const string& s, char c, vector& v) {

string::size_type i = 0;

string::size_type j = s.find(c);

while (j != string::npos) {

v.push_back(s.substr(i, j-i));

i = ++j;

j = s.find(c, j);

if (j == string::npos)

v.push_back(s.substr(i, s.length()));

}

}

int main() {

vector v;

string s = "Account Name|Address 1|Address 2 |City";

split(s, '|', v);

for (int i = 0; i < v.size(); ++i) {

cout << v[i] << '\n';

}

}

Обсуждение

Превращение приведенного выше примера в шаблон функции, принимающий любой тип символов, тривиально — просто параметризуйте тип символов и замените случаи использования stringна basic_string.

template

void split(const basic_string& s, T c,

vector >& v) {

basic_string::size_type i = 0;

basic_string::size_type j = s.find(c);

while (j != basic_string::npos) {

v.push_back(s.substr(i, j-i));

i = ++j;

j = s.find(c, j);

if (j == basic_string::npos)

v.push back(s.substr(i, s.length()));

}

}

Логика при этом не меняется.

картинка 54Однако обратите внимание, что между двумя последними угловыми скобками в последней строке заголовка функции добавлен один пробел. Это требуется для того, чтобы сказать компилятору, что это не оператор сдвига вправо.

Пример 4.10 разбивает строку с помощью простого алгоритма. Начиная с начала строки, он ищет первое вхождение разделителя с, а затем считает, что все, что стоит после начала строки или предыдущего найденного вхождения и до этого вхождения, является очередным фрагментом текста. Для поиска первого вхождения символа в оригинальной строке stringпример использует метод find, а для копирования символов диапазона в новую string, помещаемую в vector, — метод substr. Это тот же самый принцип, который используется в функциях разбиения строк большинства скриптовых языков и является специальным случаем разделения строки текста на лексемы (tokenizing) , описываемого в рецепте 4.7.

Разделение строки, использующей единственный символ-разделитель, является очень распространенной задачей, и неудивительно, что ее решение есть в библиотеке Boost String Algorithms. Оно просто в использовании. Чтобы увидеть, как разделить строку с помощью функции splitиз Boost, посмотрите на пример 4.11.

Пример 4.11. Разделение строки с помощью Boost

#include

#include

#include

#include

using namespace std;

using namespace boost;

int main() {

string s = "one,two,three,four";

list results;

split(results, s, is_any_of(",")); // Обратите внимание - это boost::split

for (list::const_iterator p = results.begin();

p != results.end(); ++p) {

cout << *p << endl;

}

}

split— это шаблон функции, принимающий три аргумента. Он объявлен вот так.

template

Seq& split(Seq& s, Coll& c, Pred p,

token_compress_mode_type e = token_compress_off);

Seq, Collи Predпредставляют типы результирующей последовательности, входной коллекции и предиката, используемого для определения, является ли очередной объект разделителем. Аргумент последовательности — это последовательность, определенная по стандарту C++, содержащая нечто, что может хранить части того, что находится во входной коллекции. Так, например, в примере 4.11 был использован list, но вместо него можно было бы использовать и vector. Аргумент коллекции — это тип входной последовательности. Коллекция — это нестандартная концепция, которая похожа на последовательность, но с несколько меньшими требованиями (за подробностями обратитесь к документации по Boost по адресу www.boost.org ). Аргумент предиката — это объект унарной функции или указатель на функцию, которая возвращает bool, указывающий, является ли ее аргумент разделителем или нет. Она вызывается для каждого элемента последовательности в виде f(*it), где it— это итератор, указывающий на элемент последовательности.

is_any_of— это удобный шаблон функции, поставляющийся в составе String Algorithms, которая облегчает жизнь при использовании нескольких разделителей. Он конструирует объект унарной функции, которая возвращает true, если переданный ей аргумент является членом набора. Другими словами:

bool b = is_any_of("abc")('a'); // b = true

Это облегчает проверку нескольких разделителей, не требуя самостоятельного написания объекта функции.

4.7. Разбиение строки на лексемы

Проблема

Требуется разбить строку на части, используя набор разделителей.

Решение

Для перебора элементов строки и поиска места нахождения следующих лексем и не-лексем используйте методы find_first_ofи first_first_not_of. Пример 4.12 представляет простой класс StringTokenizer, выполняющий эту задачу.

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать


Д. Стефенс читать все книги автора по порядку

Д. Стефенс - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




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


Отзывы читателей о книге C++. Сборник рецептов, автор: Д. Стефенс. Читайте комментарии и мнения людей о произведении.


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x