Здесь я планирую собирать некоторые ссылки, данные и так далее по заявленной теме. Пока что тут информации немного (особенно для практического применения), но меня очень интересует эта область.
«Юникодом» (википедия) называют стандарт кодирования символов, включающий символы всех алфавитов мира и дополнительные. Также «Юникодом» в узком смысле называют саму универсальную таблицу символов (в стандарте «Юникода» кроме самой таблицы символов содержится еще много чего, в частности — способы представления этих символов в компьютерах; одним из таких способов представления является кодировка UTF-8). На сентябрь 2022 года (15-я версия таблицы символов «Юникода») в таблице символов «Юникода» содержится чуть меньше 150 тысяч символов. Ни один из существующих шрифтов не реализует всю таблицу «Юникода» полностью.
- https://symbl.cc/ru/ — сайт, на котором можно просмотреть таблицу «Юникода», коды символов и их представление в разных кодировках, в том числе в кодировке UTF-8 (вообще, в интернете подобных сайтов довольно много, этот сайт — просто один из многих, особо ничем не выделяется).
Коды символов из таблицы «Юникода» записывают следующим образом, пример: U+1F60E (символ-эмодзи 😎). Здесь начало U+ обозначает, что имеется в виду символ из таблицы «Юникода». Код 1F60E — это шестнадцатеричный код символа в таблице «Юникода». При представлении символа из «Юникода» в одной из соответствующих кодировок не гарантируется, что код символа останется без изменений. Вот представление этого символа в разных кодировках, реализующих таблицу «Юникода»:
- кодировка UTF-8:
F0 9F 98 8E(4 байта, код1F60Eне сохранился); - UTF-16BE:
D8 3D DE 0E(4 байта, код1F60Eне сохранился); - UTF-16LE:
3D D8 0E DE(то же, что и в UTF-16BE, только байты в парах поменяны местами); - UTF-32BE:
00 01 F6 0E(4 байта, код1F60Eвиден, сохранился); - UTF-32LE:
0E F6 01 00(то же, что и в UTF-32BE, только байты развернуты в обратном порядке).
В чем отличие кодировки UTF-8 от других кодировок, реализующих таблицу «Юникода»? В кодировке UTF-8 разные символы представляются разным количеством байтов (в UTF-16 все символы представляются 2 байтами или парами по 2 байта, в UTF-32 все символы представляются 4 байтами). Например, для представления эмодзи в UTF-8 требуется 4 байта, для представления китайских иероглифов — 3 байта, для представления букв русского алфавита — 2 байта, для представления букв английского алфавита — 1 байт.
Переменный размер символов в UTF-8 имеет свои преимущества и недостатки. В качестве преимущества представляется то, что текст в кодировке UTF-8 занимает меньше места, чем текст в других кодировках, реализующих таблицу «Юникода» (это экономит место на диске и увеличивает скорость передачи текста по сетям). Однако, текст, в котором все символы занимают разное количество байтов, сложнее обрабатывать в программах, алгоритмы обработки получаются более заковыристые, чем для кодировок UTF-16 и UTF-32.
Начало таблицы «Юникода» (первые 128 символов) полностью совпадает с таблицей символов ASCII (в таблицу символов ASCII, как известно, входят символы английского алфавита). В кодировке UTF-8 представление первых 128 символов таблицы «Юникода» полностью совпадает с представлением символов по таблице ASCII, в том числе и по размеру (1 байт). Это еще одно из преимуществ кодировки UTF-8 (в кодировках UTF-16 и UTF-32 представление первых 128 символов отличается от представления символов по таблице ASCII из-за размеров, больших, чем 1 байт на один символ).
Существует международный стандарт ISO/IEC 10646, который тоже содержит универсальную таблицу символов. Дело в том, что изначально стандарт «Юникода» был создан и поддерживается до сих пор консорциумом (некоммерческая организация), расположенным в США. Для международной стандартизации таблицы «Юникода» был создан стандарт ISO/IEC 10646. В принципе, эти две таблицы должны полностью совпадать, но формально стандарт ISO/IEC 10646 при введении в таблицу «Юникода» новых символов на какой-то период времени может отставать от американского стандарта «Юникода», «нагоняя» его позже.
Следует иметь в виду, что в стандарте языка C++ упоминается именно международный стандарт ISO/IEC 10646.
- UTF-8 Everywhere (UTF-8 повсюду) — статья-манифест (опубликована примерно в 2012 году, написана еще раньше), призывающая использовать кодировку UTF-8 вместо всех остальных кодировок для хранения текста в компьютерах. В этой статье даны некоторые наметки, как работать с кодировкой UTF-8 (но там нет четкой и понятной инструкции!);
- Обучение C++, UTF-8 с первой программы — моя статья на «Хабре», написанная в 2023 году.
Полезные статьи в справочнике «CppReference.com»
Строго говоря, этот справочник не является стандартом языка программирования C++, но очень скрупулезно старается следовать стандарту. Можно сказать, что он очень близок к стандарту (стремится полностью совпадать), но в нем совсем по-другому (более удобно для употребления) структурирована информация, добавлены примеры применения и так далее. Я пользуюсь этим справочником очень часто.
Статьи в списке ниже я расположил в том порядке, в котором (по моему мнению) их следует читать. Можно сказать, что ссылки на более важные статьи расположены в начале списка.
- Character sets and encodings (наборы символов и кодировки);
- Escape sequences (управляющие последовательности);
- ASCII Chart (таблица символов ASCII);
- Fundamental types (фундаментальные типы) — статья включает информацию про символьные типы:
char,signed char,unsigned char,wchar_t,char8_tи так далее. В статье сказано, что по стандарту языка C++ размер значения типаcharвсегда равен 1 байту (в одном байте по стандарту языка C++ содержится не менее 8 битов, то есть может быть ровно 8 битов или более); - Character literal (символьные литералы);
- Null-terminated multibyte strings (строки с многобайтовыми символами, конец строки маркируется нулевым символом
'\0').
При чтении сайта-учебника «LearnCpp.com» я экспериментирую с вводом символов в кодировке UTF-8 из консоли и выводом их в консоль:
Мои советы в комментариях к подглаве (уроку) 4.11 «Chars» учебника «LearnCpp.com» (получились довольно объемные и информативные, на английском; загружаются не сразу, нужно немного подождать после начала загрузки страницы сайта):