Разница между MBCS и UTF-8 на Windows
Я читаю о наборе символов и кодировок в Windows. Я заметил, что в компиляторе Visual Studio (для C++) есть два флага компилятора, называемые MBCS и UNICODE. В чем разница между ними ? То, что я не получаю,-это то, как UTF-8 концептуально отличается от кодировки MBCS ? Кроме того, я нашел следующую цитату в MSDN:
Unicode-это 16-битная кодировка символов
это перечеркивает все, что я читал о Юникод. Я думал, что unicode может быть закодирован с различными кодировками, такими как UTF-8 и UTF-16. Может кто-нибудь пролить еще немного света на эту путаницу?
4 ответа:
я заметил, что есть два компилятора флаги в компиляторе Visual Studio (для В C++) называется многобайтовых кодировок и Unicode. Что в чем разница между ними ?
многие функции в Windows API поставляются в двух версиях: одна, которая принимает
char
параметры (в кодовой странице для конкретного языка) и тот, который принимаетwchar_t
параметры (в UTF-16).int MessageBoxA(HWND hWnd, const char* lpText, const char* lpCaption, unsigned int uType); int MessageBoxW(HWND hWnd, const wchar_t* lpText, const wchar_t* lpCaption, unsigned int uType);
каждая из этих пар функций также имеет макрос без суффикса, который зависит от того, является ли макрос.
#ifdef UNICODE #define MessageBox MessageBoxW #else #define MessageBox MessageBoxA #endif
для того, чтобы сделать эту работу, то
TCHAR
тип определяется для абстрагирования типа символов, используемого функциями API.#ifdef UNICODE typedef wchar_t TCHAR; #else typedef char TCHAR; #endif
это, однако, плохая идея. Вы всегда должны явно указывать тип символа.
то, что я не получаю, как UTF-8 концептуально отличается от МБК кодирование ?
кодировка расшифровывается как "многобайтных символов набор." Для буквального мышления, похоже, что UTF-8 будет квалифицироваться.
но в Windows " MBCS "относится только к кодировкам символов, которые могут использоваться с версиями" A " функций API Windows. Это включает в себя кодовые страницы 932 (Shift_JIS), 936 (GBK), 949 (KS_C_5601-1987) и 950 (Big5), но не UTF-8.
чтобы использовать UTF-8, вы должны преобразовать строку в UTF-16 с помощью
MultiByteToWideChar
, вызовите" W " версию функции и вызовитеWideCharToMultiByte
на выходе. Это по существу то, что на самом деле делают функции" A", что заставляет меня задаться вопросом почему Windows не просто поддерживает UTF-8.это неспособность поддерживать наиболее распространенная кодировка символов делает версию" A " API Windows бесполезной. Поэтому вы должны всегда используйте функции "W".
Unicode-это 16-битная кодировка символов
это перечеркивает все, что я читал о Юникод.
MSDN ошибается. Unicode-это 21-битный кодированный набор символов, который имеет несколько кодировок, наиболее распространенными из которых являются UTF-8, UTF-16 и UTF-32. (Существуют и другие кодировки Юникода, такие как GB18030, UTF-7 и UTF-EBCDIC.)
всякий раз, когда Microsoft ссылается на "Unicode", они действительно означают UTF-16 (или UCS-2). Это по историческим причинам. Windows NT был ранним последователем Unicode, когда считалось, что 16 бит достаточно для всех, а UTF-8 использовался только по плану 9. Так что UCS-2 был Unicode.
_MBCS и символ _unicode макросы, чтобы определить, какая версия в файле TCHAR.H процедуры для вызова. Например, если вы используете
_tcsclen
чтобы подсчитать длину строки, препроцессор будет отображать_tcsclen
в другую версию в соответствии с двумя макросами: _MBCS и _UNICODE._UNICODE & _MBCS Not Defined: strlen _MBCS Defined: _mbslen _UNICODE Defined: wcslen
чтобы объяснить разницу этих функций подсчета длины строк, рассмотрим следующий пример.
Если у вас есть компьютер, который работает под управлением Windows Simplified Chinese edition, которые используют GBK(936 кодовая страница), вы компилируете исходный файл в кодировке gbk-file и запускаете его.printf("%d\n", _mbslen((const unsigned char*)"I爱你M")); printf("%d\n", strlen("I爱你M")); printf("%d\n", wcslen((const wchar_t*)"I爱你M"));
результат будет
4 6 3
.вот шестнадцатеричное представление
I爱你M
в GBK.GBK: 49 B0 AE C4 E3 4D 00
_mbslen знает, что эта строка закодирована в GBK, поэтому она может правильно интепретировать строку и получить правильный результат
4
слова:49
какI
,B0 AE
как爱
,C4 E3
как你
,4D
какM
.функция strlen знает только
0x00
, вот и получилось6
.wcslen считают, что этот массив hexdeciaml кодируется в UTF16LE, и он считает два байта как одно слово, поэтому он получает
3
слова:49 B0
,AE C4
,E3 4D
.как указал @xiaokaoy, единственный действительный Терминатор для
wcslen
и00 00
. Таким образом, результат не гарантируется3
если следующий байт не00
.
MBCS означает Многобайтовый Набор Символов и описывает любой набор символов, где символ кодируется (возможно) более чем в 1 байт.
The ANSI/ ASCII наборы символов не являются многобайтовыми.
UTF-8, однако, является многобайтовой кодировки. Он кодирует любой символ Юникода в виде последовательности 1, 2, 3, или 4 октета (байта).
однако UTF-8-это только один из несколько возможных конкретных кодировок набора символов Unicode. Примечательно, что UTF-16-это еще одна кодировка, используемая Windows / .NET (IIRC). Вот разница между UTF-8 и UTF-16:
UTF-8 кодирует любой символ Юникода в виде последовательности 1, 2, 3, или 4 байта.
UTF-16 кодирует большинство символов Юникода как 2 байта, а некоторые как 4 байта.
поэтому не исправить этот Юникод является 16-битной кодировкой символов. Это скорее что-то вроде 21-битной кодировки (или даже больше в наши дни), поскольку она включает в себя набор символов с кодовыми точками
U+000000
доU+10FFFF
.
в качестве сноски к другим ответам MSDN имеет документ общие текстовые сопоставления в TCHAR.H С удобными таблицами, суммирующими, как директивы препроцессора _UNICODE и _MBCS изменяют определение различных типов C/C++.
Что касается формулировки "Unicode" и "Многобайтовый набор символов", люди уже описали, что такое эффекты. Я просто хочу подчеркнуть, что оба они являются Microsoft-говорят о некоторых очень конкретных вещах. (То есть, они что-то значат менее общий и более конкретный для Windows, чем можно было бы ожидать, если исходить из понимания интернационализации текста, не относящегося к Microsoft.) Эти точные фразы появляются и, как правило, получают свои собственные отдельные разделы / подразделы технических документов microsoft, например, в текст и строки в Visual C++