Этот сайт использует cookies. Продолжение работы с сайтом означает, что Вы согласны!
Типы char16_t и char32_t
Стандарт C++11 ввел в язык C++ два новых типа char16_t
и char32_t
.
Тип char16_t
описывает символ в кодировке UTF-16. При инициализации символа или строки перед литералом указывается строчная буква u
:
std::setlocale(LC_ALL, "Russian_Russia.1251");
char16_t ch = u'я';
std::cout << ch << std::endl; // 1103
char16_t str[] = u"строка";
size_t size = sizeof(char16_t);
std::cout << size << std::endl; // 2
size_t size_str = sizeof(str);
std::cout << size_str << std::endl; // 14
int len = static_cast<int>(size_str / size);
std::cout << len << std::endl; // 7
for (int i = 0; i < len; ++i) {
std::cout << str[i] << ' ';
} // 1089 1090 1088 1086 1082 1072 0
Тип char32_t
описывает символ в кодировке UTF-32. При инициализации символа или строки перед литералом указывается прописная буква U
:
std::setlocale(LC_ALL, "Russian_Russia.1251");
char32_t ch = U'я';
std::cout << ch << std::endl; // 1103
char32_t str[] = U"строка";
size_t size = sizeof(char32_t);
std::cout << size << std::endl; // 4
size_t size_str = sizeof(str);
std::cout << size_str << std::endl; // 28
int len = static_cast<int>(size_str / size);
std::cout << len << std::endl; // 7
for (int i = 0; i < len; ++i) {
std::cout << str[i] << ' ';
} // 1089 1090 1088 1086 1082 1072 0
Начиная со стандарта C++11, язык C++ поддерживает raw-строки, внутри которых специальные символы трактуются как комбинации обычных символов, поэтому их экранировать не нужно. Форматы raw-строк:
uR"(текст строки UTF-16)"
UR"(текст строки UTF-32)"
uR"символы(текст строки UTF-16)символы"
UR"символы(текст строки UTF-32)символы"
При использовании первых двух форматов текст строки указывается между отрывающей комбинацией символов uR"(
(или UR"(
для строк в кодировке UTF-32) и закрывающей комбинацией символов )"
:
char16_t str[] = uR"(текст \n)";
// char32_t str[] = UR"(текст \n)";
int len = static_cast<int>(sizeof(str) / sizeof(str[0]));
for (int i = 0; i < len; ++i) {
std::cout << str[i] << ' ';
} // 1090 1077 1082 1089 1090 32 92 110 0
std::cout << std::endl;
Обратите внимание, символ перевода строки \n
трактуется как комбинация двух символов \
и n
, а не как специальный символ.
Последние два формата позволяют дополнительно указать произвольные символы-разделители, например, три точки. Благодаря этим символам мы можем в тексте строки использовать любые символы без опасения, что они случайно станут закрывающей строку комбинацией символов:
char16_t str[] = uR"...(текст \n)...";
Для преобразования типов предназначены следующие функции:
c16rtomb()
— преобразует символc16
из кодировки UTF-16 в кодировку, указанную с помощью локали, и записывает результат в символьный массивbuf
. Нулевой символ в массив не добавляется. Функция возвращает число байтов, записанных в массив, или значение(size_t)(–1)
в случае ошибки. Прототип функции:
#include <cuchar> /* или #include <uchar.h> */
size_t c16rtomb(char *buf, char16_t c16, mbstate_t *state);
typedef int mbstate_t;
Пример преобразования символа в кодировку windows-1251:
std::setlocale(LC_ALL, "Russian_Russia.1251");
char buf[10] = {0};
char16_t ch = u'я';
mbstate_t state = 0;
size_t count = std::c16rtomb(buf, ch, &state);
std::cout << count << std::endl; // 1
std::cout << state << std::endl; // 0
std::cout << buf[0] << std::endl; // я
std::cout << (int)buf[0] << std::endl; // -1
mbrtoc16()
— преобразует многобайтовый символ, записанный в строкуstr
, в кодировку UTF-16 и сохраняет его в переменнойpc16
. Кодировка указывается с помощью локали. Максимально просматриваетсяn
символов строкиstr
. Функция возвращает число байтов, представляющих символ,0
или значения(size_t)(–1)
,(size_t)(–2)
или(size_t)(–3)
в случае ошибки. Прототип функции:
#include <cuchar> /* или #include <uchar.h> */
size_t mbrtoc16(char16_t *pc16, const char *str, size_t n,
mbstate_t *state);
Пример:
std::setlocale(LC_ALL, "Russian_Russia.1251");
char16_t pc16 = 0;
char str[10] = "я";
mbstate_t state = 0;
size_t count = std::mbrtoc16(&pc16, str, 10, &state);
std::cout << count << std::endl; // 1
std::cout << state << std::endl; // 0
std::cout << pc16 << std::endl; // 1103
c32rtomb()
— преобразует символc32
и записывает результат в символьный массивbuf
. Нулевой символ в массив не добавляется. Функция возвращает число байтов, записанных в массив, или значение(size_t)(–1)
в случае ошибки. Прототип функции:
#include <cuchar> /* или #include <uchar.h> */
size_t c32rtomb(char *buf, char32_t c32, mbstate_t *state);
mbrtoc32()
— преобразует многобайтовый символ, записанный в строкуstr
, в символ в кодировке UTF-32 и сохраняет его в переменнойpc32
. Прототип функции:
#include <cuchar> /* или #include <uchar.h> */
size_t mbrtoc32(char32_t *pc32, const char *str, size_t n,
mbstate_t *state);
В Windows функции c32rtomb()
и mbrtoc32()
работают с многобайтовыми символами в кодировке UTF-8, а не используют настройки кодировки из локали:
char buf[10] = {0};
char32_t ch = U'я';
mbstate_t state = 0;
size_t count = std::c32rtomb(buf, ch, &state);
std::cout << count << std::endl; // 2
std::cout << state << std::endl; // 0
std::cout << (int)buf[0] << std::endl; // -47
std::cout << (int)buf[1] << std::endl; // -113
char32_t ch32 = 0;
count = std::mbrtoc32(&ch32, buf, 10, &state);
std::cout << count << std::endl; // 2
std::cout << state << std::endl; // 0
std::cout << ch32 << std::endl; // 1103
char16_t
и char32_t
, можно воспользоваться классами u16string
и u32string
(см. разд. 9.17).Помощь сайту
ЮMoney (Yandex-деньги): 410011140483022
ПАО Сбербанк:
Счет: 40817810855006152256
Реквизиты банка:
Наименование: СЕВЕРО-ЗАПАДНЫЙ БАНК ПАО СБЕРБАНК
Корреспондентский счет: 30101810500000000653
БИК: 044030653
КПП: 784243001
ОКПО: 09171401
ОКОНХ: 96130
Скриншот реквизитов