Многобайтовый UTF-8 в массивах в C++

У меня возникли проблемы при работе с 3-байтовыми символами Unicode UTF-8 в массивах. Когда они находятся в массивах символов, я получаю предупреждения о символьных константах и ​​неявных константах, но когда я использую массивы wchar_t, wcout вообще ничего не возвращает. Из-за характера проекта это должен быть массив, а не строка. Ниже приведен пример того, что я пытался сделать.

#include <iostream>
#include <string>
using namespace std;
int main()
{
    wchar_t testing[40];
    testing[0] = L'\u0B95';
    testing[1] = L'\u0BA3';
    testing[2] = L'\u0B82';
    testing[3] = L'\0';
    wcout << testing[0] << endl;
    return 0;
}

Какие-либо предложения? Я работаю с OSX.

1 ответ

Поскольку '\u0B95' требует 3 байта, он считается литералом с несколькими символами. Многозначный литерал имеет тип int и значение, определяемое реализацией. (На самом деле, я не думаю, что GCC правильно сделать это)

Ввод L префикс перед литералом делает его типом wchar_t и имеет значение, определенное реализацией (оно сопоставляется со значением в широком наборе символов выполнения, которое является расширенным набором реализации базового набора широких символов выполнения).

Стандарт C++11 предоставляет нам еще несколько типов и литералов, поддерживающих Юникод. Дополнительные типы char16_t а также char32_t, значения которого являются кодовыми точками Unicode, которые представляют символ. Они аналогичны UTF-16 и UTF-32 соответственно.

Поскольку вам нужны литералы символов для хранения символов из базовой многоязычной плоскости, вам понадобится char16_t буквальный. Это можно записать как, например, u'\u0B95', Поэтому вы можете написать свой код следующим образом, без предупреждений или ошибок:

char16_t testing[40];
testing[0] = u'\u0B95';
testing[1] = u'\u0BA3';
testing[2] = u'\u0B82';
testing[3] = u'\0';

К сожалению, библиотека ввода / вывода не очень хорошо работает с этими новыми типами.

Если вы действительно не требуете использования символьных литералов, как описано выше, вы можете использовать новые строковые литералы UTF-8:

const char* testing = u8"\u0B95\u0BA3\u0B82";

Это закодирует символы как UTF-8.

Другие вопросы по тегам