Как обрабатывать последовательности символов Юникода в C / C ++? - PullRequest
11 голосов
/ 02 сентября 2010

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

Более того, как:

-Читать строки Unicode

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

-Печать юникодных строк

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

Ответы [ 4 ]

8 голосов
/ 02 сентября 2010

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

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

Чтение строк в Юникоде

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

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

Преобразование строк в кодировке Юникод в 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 . Прелесть Unicode в том, что он отделяет обработку кодировки символов от обработки локали (за исключением специальных правил в верхнем / нижнем регистре для литовского, турецкого и азербайджанского языков).

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

3 голосов
/ 02 сентября 2010

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

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

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

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

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

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

0 голосов
/ 03 сентября 2010

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

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

0 голосов
/ 02 сентября 2010

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

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

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

...