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

Тут можно читать бесплатно Д. Стефенс - C++. Сборник рецептов. Жанр: Компьютеры и Интернет / Программирование, год -. Так же Вы можете читать полную версию (весь текст) онлайн без регистрации и SMS на сайте «WorldBooks (МирКниг)» или прочесть краткое содержание, предисловие (аннотацию), описание и ознакомиться с отзывами (комментариями) о произведении.
Д. Стефенс - C++. Сборник рецептов

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

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

Д. Стефенс - C++. Сборник рецептов читать онлайн бесплатно

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

v объявлен как const по двум причинам. Во-первых, я знаю, что я не собираюсь изменять его содержимое, так что я хочу, чтобы компилятор выдал сообщение об ошибке, если это произойдет. Компилятор гораздо лучше меня в деле поиска таких вещей, особенно когда к такому присвоению приводит тонкая семантическая или синтаксическая ошибка. Во-вторых, я хочу показать пользователям этой функции, что я ничего не делаю с их контейнером, и const — это великолепный способ сделать это. Теперь я просто должен создать обобщенную версию, которая работает с различными типами символов.

Как и в рецепте 4.6, превращение join в общий шаблон функции очень просто. Все, что требуется сделать, — это изменить заголовок, параметризовав тип символов, как здесь:

template<typename T>

void join(const std::vector<std::basic_string<T> >& v, T c,

 std::basic_string<T>& s)

Но vector может оказаться не единственным возможным входом функции. Вам может потребоваться объединить строки в стиле С. Класс string C++ предпочтительнее строк в стиле С, так что если возникает такая задача, объединяйте их в C++ string. После этого всегда можно получить версию С, вызвав метод string c_str, который возвращает указатель const на завершающийся нулем массив символов.

Пример 4.14 предлагает общую версию join, которая объединяет массив символов в string. Так как новая общая версия параметризована по типу символов, она будет работать как для массивов узких, так и для массивов широких символов.

Пример 4.14 Объединение строк в стиле C

#include <string>

#include <iostream>

const static int MAGIC_NUMBER = 4;

template<typename T>

void join(T* arr[], size_t n, T c, std::basic_string<T>& s) {

 s.clear();

 for (int i = 0; i < n; ++i) {

  if (arr[i] != NULL)

   s += arr[i];

  if (i < n-1) s += c;

 }

}

int main() {

 std::wstring ws;

 wchar_t* arr[MAGIC_NUMBER];

 arr[0] = L"you";

 arr[1] = L"ate";

 arr[2] = L"my";

 arr[3] = L"breakfast";

 join(arr, MAGIC_NUMBER, L'/', ws);

}

4.9. Поиск в строках

Проблема

Требуется выполнить поиск в строке. Это может быть поиск одного символа, другой строки или одного из (или одного не из) неупорядоченного набора символов. И по каким-либо причинам требуется выполнять поиск в определенном порядке, например первое или последнее вхождение или первое или последнее вхождения относительно какого- либо положения в строке.

Решение

Используйте один из методов «find» из basic_string. Почти все методы поиска начинаются со слова «find», и их имена говорят достаточно о том, что они делают. Пример 4.15 показывает, как работают некоторые из этих методов поиска.

Пример 4.15. Поиск строк

#include <string>

#include <iostream>

int main() {

 std::string s = "Charles Darwin";

 std::cout << s.find("ar") << '\n'; // Поиск от

                                    // начала

 std::cout << s.rfind("ar") << "\n"; // Поиск с конца

 std::cout << s.find_first_of("swi") // Найти первое вхождение одного

  << '\n'; // из этих символов

 std::cout << s.find_first_not_of("Charles") // Найти первое,

  << '\n';                                   // что не входит в этот

                                             // набор

 std::cout << s.find_last_of("abg") << '\n'; // Найти первое вхождение любого

                                             // из этих символов,

                                             // начиная с конца

 std::cout << s.find_last_not_of("aDinrw") // Найти первое,

  << '\n';                                 // что не входит в этот

                                           // набор, начиная с конца

}

Все эти методы поиска обсуждаются более подробно в разделе «Обсуждение».

Обсуждение

Имеется шесть различных методов для поиска в строках, каждый из которых предоставляет четыре перегруженных варианта. Эти перегрузки позволяют использовать либо параметр basic_string, либо charT* (charT — это символьный тип). Каждый имеет параметр pos типа basic_string::size_type, который позволяет указать индекс, с которого следует начать поиск, и есть перегрузка с параметром n типа size_type, который позволяет выполнить поиск только n символов из набора.

Запомнить все эти методы довольно сложно, так что в табл. 4.2 дается краткая справка по каждому из них и их параметрам.

Табл. 4.2. Методы для поиска строк

Метод Описание size_type find(const basic_string& str, size_type pos = 0) const; Возвращает индекс первого вхождения символа или подстроки начиная с начала или индекса, указанного в параметре pos. size_type find (const charT* s, size_type pos, size_type n) const; size_type find (const charT* s, size_type pos = 0) const; size_type find(charT c, size_type pos = 0) const; Если указан n, то при поиске используются первые n символов целевой строки size_type rfind(...) Находит первое вхождение символа или подстроки, начиная с конца строки и двигаясь к ее началу. Другими словами делает то же, что и find, но начинает поиск с конца строки size_type find_first_of(...) Находит первое вхождение любого символа из набора, переданного как basic_string или указатель на символы. Если указан n, то ищутся только первые n символов используемого набора size_type find_last_of(...) Находит последнее вхождение любого символа из набора, переданного как basic_string или указатель на символы. Если указан n, то ищутся только первые n символов используемого набора size_type find_first_not_of(...) Находит первое вхождение любого символа, не входящего в набор, переданный как basic_string или указатель на символы. Если указан n, то принимаются во внимание только первые n символов используемого набора size_type find_last_not_of(...) Находит последнее вхождение любого символа, не входящего в набор, переданный как basic_string или указатель на символы. Если указан n, то принимаются во внимание только первые n символов используемого набора

Все эти методы возвращают индекс вхождения искомого элемента, который имеет тип basic_string<T>::size_type. Если поиск заканчивается неудачей, возвращается basic_string<T>::npos, которое является специальным значением (обычно -1), указывающим, что поиск был неудачен. Даже хотя обычно это значение -1, сравнивать возвращаемое значение следует именно с npos, что обеспечит переносимость. Также это сделает код более понятным, так как сравнение с npos является явной проверкой, не содержащей магических чисел.

Имея такое многообразие алгоритмов поиска, у вас должна быть возможность найти то, что вы ищете, а если такой возможности нет, используйте свои собственные алгоритмы. Однако если basic_string не предоставляет то, что требуется, то перед написанием своего кода посмотрите на <algorithm>. Стандартные алгоритмы работают с последовательностями, используя итераторы и почти также часто — объекты функций. Для удобства и простоты переноса basic_string предоставляет итераторы, так что подключение итераторов string к стандартным алгоритмам является тривиальным. Скажем, вам требуется найти первое вхождение двух одинаковых символов подряд. Для поиска двух одинаковых расположенных рядом («расположенных рядом» означает, что их позиции отличаются на один шаг итератора, т.е. *iter == *(iter + 1)) символов в строке используйте шаблон функции adjacent_find.

std::string s = "There was a group named Kiss in the 70s";

std::string::iterator p =

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

Результатом будет итератор, указывающий на первый из двух смежных элементов.

Если вам требуется написать собственный алгоритм работы со строками, не используйте basic_string так, как это делается со строками в стиле С, используя для доступа к элементам operator[]. Используйте существующие методы. Каждая функция поиска принимает параметр size_type, указывающий индекс, с которого должен начаться поиск. Последовательно используя функции поиска, можно пройти по всей строке. Рассмотрим пример 4.16, который подсчитывает число уникальных символов в строке.

Перейти на страницу:
Вы автор?
Жалоба
Все книги на сайте размещаются его пользователями. Приносим свои глубочайшие извинения, если Ваша книга была опубликована без Вашего на то согласия.
Напишите нам, и мы в срочном порядке примем меры.
Комментарии / Отзывы
    Ничего не найдено.