C++. Сборник рецептов - [68]

Шрифт
Интервал

>#include

>#include


>using namespace std;


>template

>void removeSubstrs(basic_string& s,

> const basic_string& p) {

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

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

>  i != basic_string::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 << '\n';

>}

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

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

Проблема

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

Решение

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

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

>#include

>#include

>#include

>#include

>#include


>using namespace std;


>void toUpper(basic_string& s) {

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

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

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

> }

>}


>void toUpper& s) {

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

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

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

> }

>}


>void toLower(basic_string& s) {

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

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

>  *p = tolower(*p);

> }

>}


>void toLower(basic_string& s) {

> for (basic_string::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;

>}

Этот код производит следующий вывод.

>s = SHAZAM

>ws = WHAM

>s = shazam

>ws = wham

Обсуждение

Кто-то может подумать, что стандартный класс >string содержит метод, преобразующий всю строку к верхнему или нижнему регистру, но на самом деле это не так. Если требуется преобразовать строку символов к верхнему или нижнему регистру, это требуется делать самостоятельно.

Неудивительно, что имеется несколько способов преобразования регистра строки (и когда я говорю «строки», то имею в виду последовательность символов как узких, так и широких). Простейшим способом сделать это является использование одной из четырех функций преобразования символов >toupper, >towupper, >tolower и >towlower. Первая форма этих функций работает с узкими символами, а вторая форма (с дополнительной буквой >w) является ее эквивалентом для широких символов.

Каждая из этих функций преобразует регистр символа, используя текущие правила локали для преобразования регистра. Верхний и нижний регистры зависят от символов, используемых в текущей локали. Некоторые символы не имеют верхнего или нижнего регистра, и в этом случае указанные функции возвращают переданный им символ. За дополнительной информацией о локалях обратитесь к главе 13. Возможности C++ по работе с различными локалями довольно сложны, и я не могут уделить им сейчас достаточно места.

Выполнение собственно преобразования символов просто. Рассмотрим функцию >toUpper из примера 4.20.

>void toUpper(basic_string& s) {

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

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

>  *p = toupper(*p);

> }

>}

Строка, выделенная жирным, выполняет всю работу. Версия для широких символов почти идентична.

>void toUpper(basic_string& s) {

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

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

>  *p = towupper(*p);

> }

>}

Я перегрузил >toupper для различных типов символов потому, что не существует общей функции >toupper, преобразующей регистр символов (при условии, что не используются возможности заголовочного файла >, который я описываю ниже). Две простые функции, как приведенные выше, выполняют всю работу.

Однако есть и другой способ выполнить эту задачу, и фактором, оказывающим влияние на выбор этого способа, является необходимость использовать явные локали. Следующие версии >toUpper и >toLower


Рекомендуем почитать
Изучаем Java EE 7

Java Enterprise Edition (Java EE) остается одной из ведущих технологий и платформ на основе Java. Данная книга представляет собой логичное пошаговое руководство, в котором подробно описаны многие спецификации и эталонные реализации Java EE 7. Работа с ними продемонстрирована на практических примерах. В этом фундаментальном издании также используется новейшая версия инструмента GlassFish, предназначенного для развертывания и администрирования примеров кода. Книга написана ведущим специалистом по обработке запросов на спецификацию Java EE, членом наблюдательного совета организации Java Community Process (JCP)


Pro Git

Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.


Java 7

Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.


Фундаментальные алгоритмы и структуры данных в Delphi

Книга "Фундаментальные алгоритмы и структуры данных в Delphi" представляет собой уникальное учебное и справочное пособие по наиболее распространенным алгоритмам манипулирования данными, которые зарекомендовали себя как надежные и проверенные многими поколениями программистов. По данным журнала "Delphi Informant" за 2002 год, эта книга была признана сообществом разработчиков прикладных приложений на Delphi как «самая лучшая книга по практическому применению всех версий Delphi».В книге подробно рассматриваются базовые понятия алгоритмов и основополагающие структуры данных, алгоритмы сортировки, поиска, хеширования, синтаксического разбора, сжатия данных, а также многие другие темы, тесно связанные с прикладным программированием.


Питон — модули, пакеты, классы, экземпляры

Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.


Как пасти котов. Наставление для программистов, руководящих другими программистами

«Как пасти котов» – это книга о лидерстве и руководстве, о том, как первое совмещать со вторым. Это, если хотите, словарь трудных случаев управления IT-проектами. Программист подобен кошке, которая гуляет сама по себе. Так уж исторически сложилось. Именно поэтому так непросто быть руководителем команды разработчиков. Даже если вы еще месяц назад были блестящим и дисциплинированным программистом и вдруг оказались в роли менеджера, вряд ли вы знаете, с чего надо начать, какой выбрать стиль руководства, как нанимать и увольнять сотрудников, проводить совещания, добиваться своевременного выполнения задач.