Как обрабатывать последовательности символов Unicode в C/С++?

Каковы более переносимые и чистые способы обработки последовательностей символов Unicode в C и С++?

Кроме того, как:

-Учитывать строки Unicode

-Конвертировать строки Unicode в ASCII для сохранения нескольких байтов (если пользователь вводит только ASCII)

-Печать строк Unicode

Должен ли я использовать среду? Например, я читал о LC_CTYPE, должен ли я заботиться об этом как разработчик?

Ответ 1

Чем более переносимым и чистым способы обработки символов Unicode последовательности в C и С++?

Имейте все строки в вашей программе UTF-8, UTF-16 или UTF-32. Если по какой-то причине вам нужно работать с кодировкой, отличной от Юникода, выполните преобразование на входе и выходе.

Прочитайте строки Unicode

То же самое, что вы читали бы ASCII файл. Но по-прежнему много данных, отличных от Unicode, поэтому вы хотите проверить, являются ли данные Unicode. Если это не так (или если UTF-8, когда ваша предпочтительная внутренняя кодировка - UTF-32), вам нужно будет ее преобразовать.

  • UTF-8 и UTF-32 могут быть надежно обнаружены путем проверки.
  • UTF-16 может быть обнаружен наличием спецификации.
  • Если это не кодировка UTF, скорее всего это будет в ISO-8859-1 или windows-1252.

Преобразование строк в Unicode в ASCII сохранить несколько байтов (если только пользователь входы ASCII)

не делать. Если ваши данные все ASCII, то UTF-8 будет занимать ровно столько же места. И если это не так, вы потеряете информацию при конвертации в ASCII. Если вы хотите сохранить байты.

  • Выберите оптимальную кодировку UTF. Для символов U + 0000 - U + 007F UTF-8 является наименьшим. Для символов U + 0800 - U + FFFF UTF-16 является наименьшим.
  • Используйте сжатие данных, например gzip. Существует кодировка SCSU, специально разработанная для Unicode, но я не знаю, насколько она хороша.

Печать строк Unicode

Запись UTF-8 ничем не отличается от написания ASCII.

За исключением командной строки Windows, поскольку она по-прежнему использует старые кодовые страницы OEM. Там вы можете использовать WriteConsoleW с строками UTF-16.

Должен ли я использовать среду? Например, я читал о LC_CTYPE, я должен заботиться об этом как разработчик

LC_CTYPE является задержкой с тех дней, когда каждый язык имел свою собственную кодировку символов и, следовательно, свои собственные функции ctype.h. Сегодня это Unicode Character Database. Красота Unicode заключается в том, что он отделяет обработку кодировки символов от обработки локали (за исключением специальных правил верхнего и нижнего регистра для литовских, турецких и азербайджанских).

Но каждый язык по-прежнему имеет свои собственные правила сортировки и правила форматирования чисел, поэтому вам все равно нужны локали для них. И вам нужно будет установить кодировку вашего языка в UTF-8.

Ответ 2

Каковы более переносимые и чистые способы обработки последовательностей символов Unicode в C и С++?

Используйте библиотеку, например ICU. Если вы не можете, это абсурдно-чертовски - не может рулонировать. Будьте готовы к трудному времени. Кроме того, посмотрите Unicode.or g документацию на исходный код образца.

Должен ли я использовать среду тоже?

Да. Возможно, вам также понадобится использовать функцию std::setlocale. Это позволит вам установить локаль, соответствующую кодировке, которую вы хотите, например. если вы хотите использовать британский английский как язык и UTF-8 в качестве кодировки, вы установите LC_CTYPE в en_ GB.UTF8.

С++ 03 не дает вам возможности работать с Unicode. Лучше всего использовать тип данных wchar_t (и по расширению std::wstring). Однако обратите внимание, что размер и кодировка символов различны для разных ОС. Например. Windows использует 2 байта для кодировки wchar_t и UTF-16, тогда как GNU/Linux и Mac OSX используют 4 байта и UTF-32.

Предполагается, что С++ 0x изменит ситуацию, разрешив символы Unicode codecvt, поддержку C Unicode TR (прочитайте <uchar.h>) и т.д., но затем это длинный путь для большинства компиляторов. (Здесь есть несколько вопросов, которые должны помочь вам начать работу.)

Ответ 3

Вам нужно прочитать, распечатать или преобразовать Unicode в ASCII, если он подходит? Просто используйте UTF-8, и все это будет абсолютно прозрачно для вас.

  • Чтение, отсутствие разницы
  • ASCII уже является подмножеством UTF-8

Для анализа и обработки текста используйте хорошие библиотеки, такие как ICU, Boost.Locale или даже Qt, Glib, которые предоставляют неплохие инструменты для анализа текста и обработки.

Ответ 4

Есть хорошие ответы, написанные здесь перед этим, но ни один из них не упомянул одну вещь, которую я рассматриваю как вероятную проблему, так как этот вопрос имеет также тег C. Мои знания C устарели, поэтому, пожалуйста, исправьте меня, если я ошибаюсь.

Обратите внимание, что предположительно строки с нулевым завершением, традиционные строковые функции C и кодированный поток данных UTF-16, вероятно, сложная комбинация, потому что в UTF-16 многие западные буквенно-цифровые символы будут закодированы в два байта, у которых есть другой байт, все нули и поэтому чтение символьных данных, как серия char, не то, что раньше было с однобайтовыми кодировками.