Разработка приложения для использования UTF-8 или UTF-16

Я разрабатываю приложение, которое в основном будет использоваться читателями на английском и испанском языках. Однако в будущем я хотел бы иметь возможность поддерживать более расширенные языки, такие как японский. Размышляя о дизайне программы, я наткнулся на стену в сравнении UTF-8, UTF-16 и multibyte. Я хотел бы скомпилировать свою программу для поддержки UTF-8 или UTF-16 (если используются такие языки, как китайский). Чтобы это произошло, я подумал, что у меня должно быть что-то вроде

#if _UTF8
typedef char char_type;
#elif _UTF16
typedef unsigned short char_type;
#else
#error
#endif

Таким образом, в будущем, когда я буду использовать UTF-16, я могу переключить #define (и, конечно же, использовать тот же тип # if / # endif для таких вещей, как sprintf и т. Д.). У меня есть свой собственный строковый тип, так что я тоже могу использовать этот случай.

Будет ли замена любого использования только одного использования «char» моим «char_type» с использованием сценария, упомянутого выше, считаться «плохой идеей»? Если да, то почему это считается плохой идеей и как я могу достичь того, о чем упоминал выше?

Причина, по которой я хотел бы использовать тот или иной, связана с эффективностью памяти. Я бы предпочел не использовать UTF-16 все время, если я его не использую.


person chadb    schedule 22.01.2012    source источник
comment
Значит, английский и испанский являются основными языками, а японский - расширенным? Например, базовое здравоохранение или отбеливание зубов?   -  person Kerrek SB    schedule 22.01.2012
comment
Не беспокойся. Сделайте свое внутреннее представление UTF32, используя char32_t, если можете, и предоставьте чистые интерфейсы.   -  person Kerrek SB    schedule 22.01.2012
comment
Я не уверен, была ли это шутка, однако я не имела в виду, потому что, похоже, я грубо говорил на том или ином языке. Я просто пытался объяснить, почему задаю этот вопрос. Мне искренне жаль, если мой вопрос был интерпретирован как неуважение   -  person chadb    schedule 22.01.2012
comment
@Kerrek SB, пожалуйста, посмотрите мою исправленную редакцию.   -  person chadb    schedule 22.01.2012
comment
Дело в том, что вы не должны думать о каком-либо одном языке как о более базовом, чем любой другой. Просто спроектируйте свою программу с самого начала, чтобы она работала с любым вводом, и вы получите гораздо более чистый результат. (Кроме того, никогда не используйте UTF16 для внутренних целей, так как это бесполезно. Он по-прежнему имеет переменную длину и добавляет другие проблемы. Вам не нужно беспокоиться о пространстве в памяти программы.)   -  person Kerrek SB    schedule 22.01.2012
comment
Я хотел бы быть более эффективным с точки зрения памяти, а не просто всегда использовать максимально возможное значение   -  person chadb    schedule 22.01.2012
comment
@chadb есть еще один встроенный тип wchar_t, который используется для utf16. В Linux он 32-битный, в Windows 16. Он используется в std :: wstring. Таким образом, использование wchar_t упрощает вашу жизнь.   -  person David Feurle    schedule 22.01.2012
comment
Мне еще не приходилось сталкиваться с ситуацией, когда wchar_t облегчал мне жизнь. Это постоянно приводило к беспорядку и добавляло сложности.   -  person StilesCrisis    schedule 22.01.2012
comment
@KerrekSB: UTF-8 также имеет переменную длину, и не без проблем. UTF-8 более компактен, чем UTF-16 для языков на основе латиницы, но менее компактен для языков Восточной Азии. UTF-16 легче искать, чем UTF-8, особенно в обратном направлении. UTF-16, как правило, легче анализировать, чем UTF-8, поскольку UTF-8 имеет больше вариаций, которые нужно учитывать (символы Unicode могут быть 1, 2, 3 или 4 байта), чем UTF-16 (символы Unicode либо 2 или 4 байта). Большинство популярных языков программирования / библиотек обычно используют / отдают предпочтение UTF-16, а не UTF-8. UTF-8, как правило, лучше использовать для хранения и связи   -  person Remy Lebeau    schedule 04.01.2017


Ответы (3)


UTF-8 может представлять каждый символ Юникода. Если ваше приложение должным образом поддерживает UTF-8, вы золотая середина для любого языка.

Обратите внимание, что собственные элементы управления Windows не имеют API-интерфейсов для установки в них текста UTF-8, если вы пишете приложение Windows. Однако легко создать приложение, которое использует UTF-8 внутренне для всего и преобразует UTF-8 -> UTF-16 при установке текста в Windows и конвертирует UTF-16 -> UTF-8 при получении текста из Windows. Я сделал это, и это сработало потрясающе и было НАМНОГО приятнее, чем писать приложение WCHAR. Преобразовать UTF-8 ‹-> 16 несложно; В Windows есть API для этого, или вы можете найти простую (одностраничную) функцию, чтобы сделать это в своем собственном коде.

person StilesCrisis    schedule 22.01.2012
comment
Если я должен всегда использовать UTF8, то почему там UTF16 или почему есть варианты в некоторых идеях, например, Visual Studio для Unicode или Multibyte? - person chadb; 22.01.2012
comment
@chadb, вариант Multibyte предназначен для старых программ, которые все еще работали с кодовыми страницами. Поскольку Windows перешла на UTF-16 внутри компании, нет причин использовать его. Что касается Windows, то Unicode означает UTF-16, что очень жаль, поскольку UTF-8 лучше для большинства целей. - person Mark Ransom; 22.01.2012
comment
@StilesCrisis, если UTF8 может представлять каждый символ Unicode, то почему Windows не является просто UTF8, а не UTF16? - person chadb; 22.01.2012
comment
К сожалению, Microsoft реализовала весь свой код Unicode до того, как стал популярным UTF8. - person StilesCrisis; 22.01.2012
comment
Microsoft перешла на UTF-16 в Windows 2000. До этого в Windows NT4 вместо этого использовался UCS-2. Windows должна была использовать UTF-16, чтобы оставаться обратно совместимой с существующим кодом, и продолжает делать это по сей день. - person Remy Lebeau; 22.01.2012
comment
Обратите внимание, что utf16 сам по себе также является многобайтовым набором символов (добавляет такую ​​же сложность, что и utf8). UCS-2 не использовался, но больше не используется. - person David Feurle; 22.01.2012
comment
@chadb: срочно прочтите programmers.stackexchange .com / questions / 102205 /. И огромное +1 от меня к StilesCrisis! - person Yakov Galka; 22.01.2012
comment
Казалось бы, я должен просто везде использовать UTF8 (char) и не использовать какой-либо тип UTF16, а использовать мой собственный пользовательский тип, который я бы переключил. Это вывод? - person chadb; 22.01.2012
comment
Что вы имеете в виду под нестандартным типом? - person StilesCrisis; 22.01.2012
comment
Под настраиваемым типом я подразумеваю то, что я опубликовал в своем исходном сообщении char_type. - person chadb; 22.01.2012
comment
Нет. С UTF8 вы просто используете char. Использование нестандартного типа упускает из виду. - person StilesCrisis; 23.01.2012
comment
Хорошо, похоже, это все проясняет. Я просто буду использовать char и не буду беспокоиться о поддержке UTF16. - person chadb; 23.01.2012

Я считаю, что выбора UTF-8 достаточно для ваших нужд. Имейте в виду, что char_type, как указано выше, меньше символа в обеих кодировках.

Возможно, вы захотите взглянуть на это обсуждение: https://softwareengineering.stackexchange.com/questions/102205/should-utf-16-be-considered-harmful из-за преимуществ различных типов популярных кодировок.

person Pavel Radzivilovsky    schedule 22.01.2012
comment
Как тогда я могу эффективно использовать UTF8 в моем коде? Нужно ли мне использовать char_type как другой typedef, чем просто char? Если да, то какого типа? - person chadb; 22.01.2012
comment
Вы просто используете обычные строки символов, которые содержат данные UTF8. Никаких новых типов не требуется. - person StilesCrisis; 23.01.2012
comment
Согласен с SC; только учтите, что char - это не символ (он меньше). - person Pavel Radzivilovsky; 23.01.2012
comment
char не символ (он меньше), мне нравится каламбур. - person Yakov Galka; 30.06.2012

По сути, это то, что Windows делает с TCHAR (за исключением того, что Windows API интерпретирует char как кодовую страницу "ANSI" вместо UTF-8).

Думаю, это плохая идея.

person dan04    schedule 23.01.2012