Да - благодаря большей осведомленности о локалях и кодировках.
В Windows есть два вызова функций для всего, что требует текста: FoobarA () и FoobarW ().Функции * W () принимают строки в кодировке UTF-16, * A () принимает строки в текущей кодовой странице.Однако Windows не поддерживает кодовую страницу UTF-8, поэтому вы не можете напрямую использовать ее в этом смысле с функциями * A (), и при этом вы не хотите зависеть от того, что установлено пользователями.Если вы хотите использовать Unicode в Windows, используйте функции с поддержкой Unicode (* W).Существуют учебные пособия, которые вы можете найти в Googling «Учебник по Unicode Windows».
Если вы храните данные UTF-8 в std :: string, то перед тем, как передать их в Windows, преобразуйте их вUTF-16 (Windows предоставляет функции для этого), а затем передает его в Windows.
Многие из этих проблем возникают из-за того, что C / C ++ обычно не зависит от кодировки.char
на самом деле не персонаж, это просто целостный тип.Даже использование массивов char
для хранения данных UTF-8 может создать проблемы, если вам потребуется доступ к отдельным кодовым единицам, поскольку подпись char
не определена стандартами.Оператор типа str[x] < 0x80
для проверки многобайтовых символов может быстро привести к ошибке.(Это утверждение всегда верно, если char
подписано.) Единица кода UTF-8 - это целочисленный тип без знака с диапазоном 0-255.Это точно соответствует типу C uint8_t
, хотя unsigned char
также работает.В идеале тогда я бы сделал строку UTF-8 массивом uint8_t
с, но из-за старых API это делается редко.
Некоторые люди рекомендовали wchar_t
, утверждая, что это "Тип символов Unicode "или что-то в этом роде.Опять же, здесь стандарт такой же независимый, как и раньше, так как C предназначен для работы где угодно и где угодно, где Unicode не используется.Таким образом, wchar_t
не более Unicode, чем char
.Стандарт гласит:
, который является целочисленным типом, диапазон значений которого может представлять различные коды для всех членов наибольшего расширенного набора символов, указанного среди поддерживаемых локалей
InLinux, wchat_t
представляет кодовую единицу UTF-32 / кодовую точку.Таким образом, это 4 байта.Однако в Windows это кодовая единица UTF-16 и занимает всего 2 байта.(Что, я бы сказал, не соответствует вышесказанному, поскольку 2 байта не могут представлять весь Unicode, но именно так он и работает.) Разница в размерах и разница в кодировании данных явно создает нагрузку на переносимость.Сам стандарт Unicode рекомендует против wchar_t
, если вам нужна мобильность.(§5.2)
Конечный урок: Мне проще всего хранить все мои данные в каком-то хорошо объявленном формате.(Обычно это UTF-8, обычно в std :: string, но мне бы хотелось что-нибудь получше.) Здесь важна не часть UTF-8, а, скорее, я знаю , что мои строкиUTF-8.Если я передаю их другому API, я также должен знать , что этот API ожидает строки UTF-8.Если это не так, то я должен преобразовать их.(Таким образом, если я говорю с API-интерфейсом Window, я должен сначала преобразовать строки в UTF-16.) Текстовая строка UTF-8 представляет собой «оранжевый», а текстовая строка «latin1» - «яблоко».Массив char
, который не знает, в какой кодировке он находится, - это путь к катастрофе.