Чтение онлайн

на главную - закладки

Жанры

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

Когсуэлл Джефф

Шрифт:

void toUpper(basic_string<wchar_t>& s) {

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

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

*p = towupper(*p);

 }

}

Я перегрузил

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

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

toUpper
и
toLower
преобразуют регистр строк независимо от типа их символов, но при условии, что указанная локаль (а по умолчанию текущая) поддерживает преобразование регистра для данного типа символов.

template<typename С>

void toUpper2(basic_string<C>& s, const locale& loc = locale) {

 typename basic_string<C>::iterator p;

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

*p = use_facet<ctype<C> >(loc).toupper(*p);

 }

}

template<typename C>

void tolower2(basic_string<C>& s, const locale& loc = locale) {

 typename basic_string<C>::iterator p;

 for (p = s.begin, p ! = s.end(++p) {

*p = use_facet<ctype<C> >(loc).tolower(*p);

 }

}

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

<locale>
. За более подробным обсуждением локалей и возможностей интернационализации обратитесь к главе 13.

4.13. Выполнение сравнения строк без учета регистра

Проблема

Имеются две строки и требуется узнать, не равны ли они, не учитывая регистр их символов. Например, «cat» не равно «dog», но «Cat» должна быть равна «cat», «CAT» или «caT».

Решение

Сравните строки, используя стандартный алгоритм

equal
(определенный в
<algorithm>
), и создайте свою собственную функцию сравнения, которая использует для сравнения версий с верхним регистром символов функцию
toupper
из
<cctype>
(или
towupper
из
<cwctype>
для широких символов). Пример 4.21 показывает обобщенное решение. Также он демонстрирует использование и гибкость STL. За полным объяснением обратитесь к обсуждению ниже.

Пример 4.21. Сравнение строк без учета регистра

1 #include <string>

2 #include <iostream>

3 #include <algorithm>

4 #include <cctype>

5 #include <cwctype>

6

7 using namespace std;

8

9 inline bool caseInsCharCompareN(char a, char b) {

10 return(toupper(a) == toupper(b));

11 }

12

13 inline bool caseInsCharCompareW(wchar_t a, wchar_t b) {

14 return(towupper(a) == towupper(b));

15 }

16

17 bool caseInsCompare(const string& s1, const string& s2) {

18 return((s1.size == s2.size) &&

19 equal(s1.begin, s1.end, s2.begin, caseInsCharCompareN));

20 }

21

22 bool caseInsCompare(const wstring& s1, const wstring& s2) {

23 return((s1.size == s2.size)

24 equal(s1.begin, s1.end, s2.begin, caseInsCharCompareW));

25 }

26

27 int main {

28 string s1 = "In the BEGINNING...";

29 string s2 = "In the beginning...";

30 wstring ws1 = L"The END";

31 wstring ws2 = L"the end";

32

33 if (caseInsCompare(s1, s2))

34 cout << "Equal!\n";

35

36 if (caseInsCompare(ws1, ws2))

37 cout << "Equal!\n";

38 }

Обсуждение

Критической

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

Строки 9-15 примера 4.21 определяют функции, которые выполняют сравнение —

caseInsCharCompareN
и
caseInsCharCompareW
. Они для преобразования символов к верхнему регистру используют
toupper
и
towupper
, а затем сообщают, равны ли они.

После написания этих функций сравнения настает время использовать стандартный алгоритм, выполняющий применение этих функций сравнения к произвольной последовательности символов. Именно это делают функции

caseInsCompare
, определенные в строках 17-25 и использующие
equal
. Здесь сделано две перегрузки — по одной для каждого типа интересующих нас символов. Они обе делают одно и то же, но каждая использует для своего типа символов соответствующую функцию сравнения. Для этого примера я перегрузил две обычные функции, но этот же эффект может быть достигнут и с помощью шаблонов. Для пояснений обратитесь к врезке «Следует ли использовать шаблон?».

Поделиться:
Популярные книги

Хозяйка старой пасеки

Шнейдер Наталья
Фантастика:
попаданцы
фэнтези
7.50
рейтинг книги
Хозяйка старой пасеки

Измена. Не прощу

Леманн Анастасия
1. Измены
Любовные романы:
современные любовные романы
4.00
рейтинг книги
Измена. Не прощу

Черный маг императора 2

Герда Александр
2. Черный маг императора
Фантастика:
юмористическая фантастика
попаданцы
аниме
6.00
рейтинг книги
Черный маг императора 2

Разбуди меня

Рам Янка
7. Серьёзные мальчики в форме
Любовные романы:
современные любовные романы
остросюжетные любовные романы
5.00
рейтинг книги
Разбуди меня

Не грози Дубровскому! Том III

Панарин Антон
3. РОС: Не грози Дубровскому!
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Не грози Дубровскому! Том III

Семья. Измена. Развод

Высоцкая Мария Николаевна
2. Измены
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Семья. Измена. Развод

Хозяин Теней 4

Петров Максим Николаевич
4. Безбожник
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Хозяин Теней 4

Сердце Дракона. Том 9

Клеванский Кирилл Сергеевич
9. Сердце дракона
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
7.69
рейтинг книги
Сердце Дракона. Том 9

Потомок бога

Решетов Евгений Валерьевич
1. Локки
Фантастика:
попаданцы
альтернативная история
аниме
сказочная фантастика
5.00
рейтинг книги
Потомок бога

Отмороженный 11.0

Гарцевич Евгений Александрович
11. Отмороженный
Фантастика:
боевая фантастика
рпг
попаданцы
фантастика: прочее
фэнтези
5.00
рейтинг книги
Отмороженный 11.0

Надуй щеки! Том 7

Вишневский Сергей Викторович
7. Чеболь за партой
Фантастика:
попаданцы
дорама
5.00
рейтинг книги
Надуй щеки! Том 7

Идеальный мир для Лекаря 21

Сапфир Олег
21. Лекарь
Фантастика:
фэнтези
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 21

Антимаг его величества. Том III

Петров Максим Николаевич
3. Модификант
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Антимаг его величества. Том III

Истребители. Трилогия

Поселягин Владимир Геннадьевич
Фантастика:
альтернативная история
7.30
рейтинг книги
Истребители. Трилогия