C/C++, Visual Studio, Юникод/Многобайтовые кодировки

194
28 ноября 2018, 16:30

В настройках проекта Visual Studio можно выбирать набор используемых символов. Обычно там есть два пункта:

Многобайтовая кодировка;
Юникод.

В чем разница?

Я раньше считал, что многобайтовая кодировка - это ANSI, 8 битные символы, зависимость от кодовой страницы. А юникод - это UTF16-LE, который обычно упаковывается в wchar_t, и при этом значащий символ может быть представлен 1 или 2 символами wchar_t.

Считал я так потому, что при выборе многобайтовой кодировки - WinAPI макросы разворачивались из, например, CreateFile() в CreateFileA(), а синоним TCHAR скрывал за собой char. То есть, многобайтовая кодировка в настройках проекта приводила к использованию ANSI версий WinAPI функций и типов.

Но теперь я окончательно запутался. Помогите разобраться в этом вопросе.

Answer 1

Самое первое, что нужно понять, что юникод и utf-XXX - это разные штуки. Самая ближайшая аналогия - классы и объекты.

Юникод - это просто таблица, в которой каждому символу сопоставлен какой то код-число.

utf-8, utf-16-le и другие - это то, как этот код-число кодируется в "железе".

То есть, самому юникоду побоку на байты, на биты. Там числа.

utf-8 сделан так, что если использовать только первые 128 символов юникода, то по внешнему виду его нельзя отличить от кодировки ANSI. Они совпадают с точностью до битового представления (если конечно не считать BOM, который может быть вначале). Эта особенность как раз и дала возможность легко добавить поддержку юникода (юникода, а не utf16).

Но у uft-8 есть один фатальный недостаток - многие функции с ним "тяжело работают". К примеру, посчитать длину строки (strlen). И тут начинаются танцы с бубном, что считать длину строки - количество байт или количество символов или количество видимых пользователю символов (ага, не все символы юникода видимы. часть из них это "модификаторы". Например, добавляем спец модификатор к И и получам Й. Длина строки будет 4 2 или 1, в зависимости от того, как считать).

В UTF16 с этим чуточку проще. Там почти всегда все символы по два байта. Длину считать легко, ну кроме тех случаев, когда кодируется двумя двухбайтовыми.

И Майкрософт решила использовать UTF16-LE. Это интересное решение, легко кодится и большинстве случаев пользователи-программисты просто поменяли свои типы на t* типы и все заработало. Но сделали глупость и назвали это "юникодом".

READ ALSO
Запись значения из QSpinBox в переменную int

Запись значения из QSpinBox в переменную int

Пытаюсь записать значение из QSpinBox в переменную int с помощью слота:

187
ошибка при работе с SceneBuilder в Eclipse

ошибка при работе с SceneBuilder в Eclipse

При запуске программы вылетает такая ошибка и ничего не запускается:

221