Я хочу написать программу на C ++, которая должна работать в Unix и Windows.
Сначала убедитесь, что вы понимаете разницу между тем, как Unix поддерживает Unicode и как Windows поддерживает Unicode.
В дни до Юникода обе платформы были похожи в том, что в каждой локали были свои предпочтительные кодировки символов.Строки были массивами char
.Один char
= один символ, за исключением нескольких восточноазиатских локалей, которые использовали двухбайтовые кодировки (с которыми было неудобно работать из-за несамосинхронизации).
Но они подошли к Unicode в двух разныхспособы.
Windows NT приняла Unicode в первые дни, когда Unicode предназначался для 16-битной кодировки символов фиксированной ширины.Microsoft написала совершенно новую версию Windows API, используя 16-разрядные символы (wchar_t
) вместо 8-разрядных символов.Для обратной совместимости они сохранили старый API "ANSI" и определили тонну макросов, чтобы вы могли вызывать либо версию "ANSI", либо "Unicode" в зависимости от того, был ли определен _UNICODE
.
ВВ мире Unix (в частности, Plan 9 от Bell Labs) разработчики решили, что будет проще расширить существующую восточноазиатскую поддержку многобайтовых символов Unix для обработки 3-байтовых символов, и создали кодировку, теперь известную как UTF-8.В последние годы Unix-подобные системы делают UTF-8 кодировкой по умолчанию для большинства локалей.
Теоретически Windows может расширить поддержку ANSI для включения UTF-8, но у них все еще нет из-за жестко закодированных предположений о максимальном размере персонажа.Итак, в Windows вы застряли с API-интерфейсом ОС, который не поддерживает UTF-8, и библиотекой времени выполнения C ++, которая не поддерживает UTF-8.
В результате вы получите следующее:
- UTF-8 - самая простая кодировка для работы в Unix.
- UTF-16 - самая простая кодировка для работы в Windows.
Это создает столько же сложностей для кроссплатформенного кода, сколько и звучит.Проще, если вы просто выберете одну кодировку Unicode и будете придерживаться ее.
Какой кодировкой это должно быть?
См. UTF-8 или UTF-16 илиUTF-32 или UCS-2
В итоге:
- UTF-8 позволяет сохранить предположение о 8-битных единицах кода.
- UTF-32 позволяет сохранить предположение о символах фиксированной ширины.
- UTF-16 отстой , но все еще существует из-за Windows и Java.
wchar_t
- это стандартный тип широких символов C ++.Но его кодировка не стандартизирована: это UTF-16 в Windows и UTF-32 в Unix.За исключением тех платформ, которые используют зависящие от локали кодировки wchar_t
в качестве наследства от восточноазиатских программ.
Если вы хотите использовать UTF-32, используйте uint32_t
или эквивалентный typedefхранить символы.Или используйте wchar_t
, если определено __STDC_ISO_10646__
и uint32_t
.
Новый стандарт C ++ будет иметь char16_t
и char32_t
, что, надеюсь, прояснит путаницу в том, как представлять UTF-16.и UTF-32.
TCHAR
- это определение типа Windows для wchar_t
(предполагается, что это UTF-16), когда определено _UNICODE
и char
(предполагается, что ANSI)") иначе.Он был разработан для работы с перегруженным Windows API, упомянутым выше.
В мое мнение , TCHAR
отстой.Он сочетает в себе недостатки зависимости от платформы char
с недостатками зависимости от платформы wchar_t
.Избегайте этого.
Самое важное соображение
Кодировки символов касаются обмена информацией.Вот что означает «II» в ASCII.Ваша программа не существует в вакууме.Вы должны читать и записывать файлы, которые с большей вероятностью будут закодированы в UTF-8, чем в UTF-16.
С другой стороны, вы можете работать с библиотеками, которые используют UTF-16 (или болеередко, UTF-32) персонажи.Это особенно верно для Windows.
Я рекомендую использовать форму кодирования, которая минимизирует количество конверсий, которое вам нужно сделать.
Эта программа должна быть в состоянии использовать
оба: Unicode и не Unicode
окружающая среда
Было бы намного лучше, если бы ваша программа работала полностью в Юникоде внутри и имела бы дело только с унаследованными кодировками для чтения устаревших данных (или записи их, но только , если явно задан вопрос).