Например, может потребоваться удалить все вхождения подстроки, а не одно из них. Или только последнее. Или седьмое. Каждый раз действия будут одни и те же: найдите индекс начала шаблона, который требуется удалить, затем вызовите erase для этого индекса и n последующих символов, где n — это длина строки шаблона. За описанием различных методов поиска подстрок обратитесь к рецепту 4.9.

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

Пример 4.19. Удаление всех подстрок из строки (обобщенная версия)

#include <string>

#include <iostream>

using namespace std;

template<typename T>

void removeSubstrs(basic_string<T>& s,

 const basic_string<T>& p) {

 basic_string<T>::size_type n = p.length();

 for (basic_string<T>::size_type i = s.find(p);

  i != basic_string<T>::npos; i = s.find(p))

  s.erase(i, n);

}

int main() {

 string s = 'One fish, two fish, red fish, blue fish';

 string p = 'fish';

 removeSubstrs(s, p);

 cout << s << ' ';

}

Здесь всю важную работу выполняет метод erase basic_string. В <string> он перегружен три раза. Использованная в примере 4.19 версия принимает индекс, с которого требуется начать удаление, и число удаляемых символов. Другая версия принимает в качестве аргументов начальный и конечный итераторы, а также есть версия, которая принимает единственный итератор и удаляет элемент, на который он указывает. Чтобы обеспечить оптимальную производительность при планировании удаления нескольких последовательных элементов, используйте первые две версии и не вызывайте s.erase(iter) несколько раз для удаления каждого из идущих подряд элементов. Другими словами, используйте методы, работающие с диапазонами, а не с одним элементом, особенно в случае тех методов, которые изменяют содержимое строки (или последовательности). В этом случае вы избежите дополнительных вызовов функции erase для каждого элемента последовательности и позволите реализации string более грамотно управлять ее содержимым.

4.12. Преобразование строки к нижнему или верхнему регистру

Проблема

Имеется строка, которую требуется преобразовать к нижнему или верхнему регистру.

Решение

Для преобразования символов к нижнему или верхнему регистру используйте функции toupper и tolower из заголовочного файла <cctype>. Пример 4.20 показывает, как использовать эти функции. Смотри также обсуждение альтернативных методик.

Пример 4.20. Преобразование регистра строки

#include <iostream>

#include <string>

#include <cctype>

#include <cwctype>

#include <stdexcept>

using namespace std;

void toUpper(basic_string<char>& s) {

 for (basic_string<char>::iterator p = s.begin();

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

  *p = toupper(*p); // toupper is for char

 }

}

void toUpper<basic_string<wchar_t>& s) {

 for (basic_string<wchar_t>::iterator p = s.begin();

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

  *p = towupper(*p); // towupper is for wchar_t

 }

}

void toLower(basic_string<char>& s) {

 for (basic_string<char>::iterator p = s.begin();

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

  *p = tolower(*p);

 }

}

void toLower(basic_string<wchar_t>& s) {

 for (basic_string<wchar_t>::iterator p = s.begin();

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

  *p = towlower(*p);

}

int main() {

 string s = 'shazam';

 wstring ws = L'wham';

 toUpper(s); toUpper(ws);

 cout << 's = ' << s << endl;

 wcout << 'ws = ' << ws << endl;

 toLower(s);

 toLower(ws);

 cout << 's = ' << s << endl;

 wcout << 'ws = ' << ws << endl;

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату