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

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

Жанры

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
. Здесь сделано две перегрузки — по одной для каждого типа интересующих нас символов. Они обе делают одно и то же, но каждая использует для своего типа символов соответствующую функцию сравнения. Для этого примера я перегрузил две обычные функции, но этот же эффект может быть достигнут и с помощью шаблонов. Для пояснений обратитесь к врезке «Следует ли использовать шаблон?».

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

Господин следователь

Шалашов Евгений Васильевич
1. Господин следователь
Детективы:
исторические детективы
5.00
рейтинг книги
Господин следователь

Ратник

Ланцов Михаил Алексеевич
3. Помещик
Фантастика:
альтернативная история
7.11
рейтинг книги
Ратник

Убивать чтобы жить 5

Бор Жорж
5. УЧЖ
Фантастика:
боевая фантастика
космическая фантастика
рпг
5.00
рейтинг книги
Убивать чтобы жить 5

Егерь

Астахов Евгений Евгеньевич
1. Сопряжение
Фантастика:
боевая фантастика
попаданцы
рпг
7.00
рейтинг книги
Егерь

Шесть принцев для мисс Недотроги

Суббота Светлана
3. Мисс Недотрога
Фантастика:
фэнтези
7.92
рейтинг книги
Шесть принцев для мисс Недотроги

Метатель

Тарасов Ник
1. Метатель
Фантастика:
боевая фантастика
попаданцы
рпг
фэнтези
фантастика: прочее
постапокалипсис
5.00
рейтинг книги
Метатель

Последний из рода Демидовых

Ветров Борис
Фантастика:
детективная фантастика
попаданцы
аниме
5.00
рейтинг книги
Последний из рода Демидовых

Башня Ласточки

Сапковский Анджей
6. Ведьмак
Фантастика:
фэнтези
9.47
рейтинг книги
Башня Ласточки

Ротмистр Гордеев

Дашко Дмитрий Николаевич
1. Ротмистр Гордеев
Фантастика:
фэнтези
попаданцы
альтернативная история
5.00
рейтинг книги
Ротмистр Гордеев

Мастер Разума II

Кронос Александр
2. Мастер Разума
Фантастика:
героическая фантастика
попаданцы
аниме
5.75
рейтинг книги
Мастер Разума II

Мама для дракончика или Жена к вылуплению

Максонова Мария
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Мама для дракончика или Жена к вылуплению

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

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

Архил...?

Кожевников Павел
1. Архил...?
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Архил...?

Невеста драконьего принца

Шторм Елена
Любовные романы:
любовно-фантастические романы
5.25
рейтинг книги
Невеста драконьего принца