Skip to content

Latest commit

 

History

History
57 lines (35 loc) · 12.1 KB

File metadata and controls

57 lines (35 loc) · 12.1 KB

Юникод (UTF-8) в C++

Здесь я планирую собирать некоторые ссылки, данные и так далее по заявленной теме. Пока что тут информации немного (особенно для практического применения), но меня очень интересует эта область.

Что такое «Юникод» и кодировка UTF-8

«Юникодом» (википедия) называют стандарт кодирования символов, включающий символы всех алфавитов мира и дополнительные. Также «Юникодом» в узком смысле называют саму универсальную таблицу символов (в стандарте «Юникода» кроме самой таблицы символов содержится еще много чего, в частности — способы представления этих символов в компьютерах; одним из таких способов представления является кодировка 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» (получились довольно объемные и информативные, на английском; загружаются не сразу, нужно немного подождать после начала загрузки страницы сайта):