Анимация
JavaScript


Главная  Библионтека 

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 [ 225 ] 226 227 228 229 230 231 232 233 234 235 236 237 238 239

Если с не является буквой нижнего регистра, функция возвращает первый аргумент без изменений.

Представленный ниже вызов и следующая за ним конструкция эквивалентны:

std::1slower(c.loc)

std:;use facet<std::ctype<char> >(loc).is(std::ctype base::lower.c)

В приведенном выражении вызывается функция is() фацета ctype<char>. Функция is() проверяет, относится ли символ с к какой-либо из категорий, определяемых маской (первый аргумент). Значения флагов маски определяются в классе ctype base. Примеры использования вспомогательных функций приведены на с. 484 и 643.

Глобальные вспомогательные функции классификации символов соответствуют одноименным функциям С, получающим только один аргумент. Эти функции определяются в заголовочных файлах <cctype> и <ctype.h> и всегда используют текущий единый локальный контекст Работать с ними еще удобнее:

if Cstd::1sdlgitCc)) { )

Тем не менее при использовании этих функций вы не сможете работать с разными локальными контекстами в одной программе, а также задействовать функции С с пользовательским фацетом ctype. Пример применения функций С для преобразования всех символов строки к верхнему регистру приведен на с. 481

Вспомогательные функции С++ не должны использоваться в тех фрагментах кода, которые критичны по быстродействию. Гораздо быстрее получить соответствующий фацет от локального контекста и работать с функциями этого объекта напрямую. Если требуется классифицировать большое количество символов в одном локальном контексте, имеется еще более эффективное решение (во всяком случае, для символов, не относящихся к типу char). Для классификации типичных символов можно воспользоваться функцией \s{beg, end, vec): эта функция строит для каждого символа из интервала [beg,end) маску с описанием свойств этого символа. Полученная маска сохраняется в элементе вектора vec, позиция которого соответствует позиции символа. Далее полученный вектор используется для быстрой идентификации символов.

Преобразование кодировок

Фацет codecvt выполняет преобразования между внутренней и внешней кодировками символов. Например, с его помощью можно преобразовывать символы из Unicode в EUC (Extended UNIX Code) при условии, что реализация стандартной библиотеки С++ поддерживает соответствующий фацет.

Этот локальный контекст идентичен глобально назначенному локальному контексту С++ только в том случае, если последний вызов locale::global() производился с именованным контекстом и функция setlocale() с тех пор це вызывалась. В противном случае локальный контекст, используемый функциями С, будет отлщшться от глобально назначенного локального контекста С++.



Этот фацет используется классом basic filebuf для преобразования между внутренней кодировкой и представлением, хранящимся в файле. Класс basic filebuf<charT,traits> (см. с. 602) задействует для этой цели специализацию codecvt <charT,char,typename traits: :state type>. Применяемый фацет берется из локального контекста, связанного с basic filebuf. Данный способ применения фацета является основным, напрямую с этим фацетом работают крайне редко.

На с. 658 были приведены начальные сведения о кодировке символов. Чтобы понять, как работает фацет codecvt, необходимо знать о существовании двух схем кодировки: в одной схеме каждый символ кодируется фиксированным количеством байтов (расширенная кодировка), а в другой используется переменное количество байтов на символ (многобайтовая кодировка).

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

Шаблон фацета codecvto получает три аргумента:

О тип символов внутреннего представления internT; О тип символов внешнего представления charT;

О тип stateT, используемый для представления промежуточного состояния в процессе преобразования.

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

Во внутреннем представлении символы всегда кодируются фиксированным количеством байтов. Как правило, программы работают с символьными данными типов char и wchar t, а во внешнем представлении может использоваться многобайтовая или расширенная кодировка, В случае многобайтовой кодировки второй аргумент шаблона определяет тип представления ее базовых единиц. Каждый многобайтовый символ состоит из одного или нескольких объектов этого типа. Обычно для этой цели применяется тип char.

В третьем аргументе передается тип, используемый для представления текущего состояния преобразования. Например, если одна из кодировок является многобайтовой, обработка многобайтового символа может быть прервана из-за переполнения исходного или приемного буфера. В этом случае текущее состояние преобразования сохраняется в объекте заданного типа.

По аналогии с другими фацетами стандарт требует обязательной поддержки минимального количества специализаций. Стандартная библиотека С++ поддерживает только две специализации:

О codecvt<char,char,mbstate t> - преобразование исходной кодировки самой в себя (вырожденная версия фацета codecvt);

О codecvt<wchar t,char,mbstate t> - преобразование между исходной «узкой» кодировкой (то есть char) и расширенной кодировкой (wchar t).



Стандарт С++ не определяет конкретную семантику второго преобразования. Единственное естественное решение заключается в разбиении каждого объекта wchar t на sizeof(wchar t) объектов типа char для преобразования wchar t в char и сборке wchar t из того же количества объектов char при обратном преобразовании. Обратите внимание на принципиальные отличия этого преобразования от тех, которые выполняются функциями widen() и narrow() фацета ctype: если функции codecvt используют биты нескольких объектов char для формирования одного объекта wchar t (или наоборот), функции ctype преобразуют символ из одной кодировки в соответствующий символ другой кодировки (если он существует).

Фацет codecvt, как и ctype, является производным от базового класса с определением перечисляемого типа. Базовый класс называется codecvt base, в нем определяется перечисляемый тип result Значения перечисляемого типа требуются при описании результатов вызова функций codecvt. Точный смысл каждого значения зависит от вызываемой функции. В табл. 14.20 перечислены функции фацета codecvt.

Таблица 14.20. Функции фацета codecvt Выражение Описание

cvt.in(s, fb, fe, fn, tb, te, tn) Преобразует внешнее представление к внутреннему

cvt.out(s, fb, fe, fn, tb, te, tn) Преобразует внутреннее представление к внешнему

cvt.unshift(s, tb, te, tn) Записывает служебную последовательность для переключения

к исходному состоянию сдвига

cvt.encodingO Возвращает информацию о внешней кодировке

cvt.aways noconv() Возвращает true, если преобразование не выполняется

cvt.length(s, fb, fe, max) Возвращает количество объектов extemT в интервале между fb

и fe для получения max символов во внутреннем представлении

cvt.maxJengthO Возвращает максимальное количество объектов externT,

необходимых для создания одного объекта internJ

Функция 1п() преобразует внешнее представление к внутреннему. Аргумент s содержит ссылку на stateT, Перед преобразованием этот аргумент определяет состояние сдвига, используемое в начале преобразования, а после преобразования в нем сохраняется итоговое состояние сдвига. Переданное состояние сдвига может отличаться от исходного, если текущий буфер не является первым из обрабатываемых буферов. Аргументы fb и fe относятся к типу const internT* и определяют соответственно начало и конец входного буфера. Аргументы tb и te относятся к типу externT* и определяют соответственно начало и конец выходного буфера. Аргументы fn (тип const extern&*&) и tn (тип internT*&) содержат ссылки, в которых возвращается конец преобразуемой последовательности символов во входном и выходном буферах соответственно. Конец любого буфера может быть достигнут до того, как будет достигнут Конец другого буфера. Функция возвращает значение типа codecvt base::result (табл. 14.21).



0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 [ 225 ] 226 227 228 229 230 231 232 233 234 235 236 237 238 239