Обработка Unicode в C ++

107

Какова наилучшая практика обработки Unicode в C ++?

Фортепьяниссимо
источник

Ответы:

81
  • Используйте ICU для работы с вашими данными (или аналогичную библиотеку)
  • Убедитесь, что в вашем собственном хранилище данных все хранится в одной кодировке.
  • Убедитесь, что вы всегда используете свою библиотеку Unicode для повседневных задач, таких как длина строки, статус использования заглавных букв и т. Д. Никогда не используйте встроенные функции стандартной библиотеки, например, is_alphaесли это не то определение, которое вам нужно.
  • Я не могу сказать достаточно: никогда не перебирайте индексы a, stringесли вы заботитесь о правильности, всегда используйте для этого свою библиотеку unicode.
дымка
источник
Если вы не обрабатываете stringдвоичные данные.
Деми
10

Если вас не волнует обратная совместимость с предыдущими стандартами C ++, текущий стандарт C ++ 11 имеет встроенную поддержку Unicode: http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2011 /n3242.pdf

Таким образом, по-настоящему лучшей практикой для обработки Unicode в C ++ было бы использование для этого встроенных средств. Однако это не всегда возможно со старыми базами кода, поскольку в настоящее время стандарт настолько новый.

РЕДАКТИРОВАТЬ: Чтобы уточнить, C ++ 11 поддерживает Unicode, поскольку теперь он поддерживает литералы Unicode и строки Unicode. Однако стандартная библиотека имеет лишь ограниченную поддержку обработки и преобразования Unicode. Для ваших текущих нужд этого может быть достаточно. Однако, если вам нужно выполнить большой объем тяжелой работы прямо сейчас, вам все равно может потребоваться что-то вроде ICU для более глубокой обработки. В настоящее время в разработке есть несколько предложений по включению более надежной поддержки преобразования текста между различными кодировками. Я предполагаю (и надеюсь), что это будет частью следующего технического отчета .

Eestrada
источник
Эта ссылка на черновик стандартной документации не очень полезна без ссылки на конкретный раздел, который описывает обсуждаемую вами «встроенную поддержку Unicode».
Бен Коллинз
1
@BenCollins Раздел 2.14.5 «Строковые литералы» - обсуждает строковые литералы, включая строковые литералы для кодировок UTF-8, UTF-16 и UTF-32. Раздел 22.4.1.4 «Шаблон класса codecvt» - обсуждает класс codecvt, используемый для преобразования между кодировками символов (включая UTF-8, UTF-16 и UTF-32). В документе есть больше о поддержке Unicode, но это, по-видимому, самые важные разделы по этому вопросу.
eestrada
9

Наша компания (и другие) используют библиотеку Internation Components for Unicode (ICU) с открытым исходным кодом, изначально разработанную Taligent.

Он обрабатывает строки, локали, преобразования, дату / время, сопоставление, преобразования и т. Д. al.

Начните с Руководства пользователя ICU

jschroedl
источник
5

Вот контрольный список для программирования Windows:

  • Все строки заключены в _T («моя строка»)
  • Функции strlen () и т. д. заменены на _tcslen () и т. д.
  • Используйте LPTSTR и LPCTSTR вместо char * и const char *
  • При запуске новых проектов в Dev Studio неукоснительно убедитесь, что опция Unicode выбрана в свойствах вашего проекта.
  • Для строк C ++ используйте std :: wstring вместо std :: string
Адам Пирс
источник
11
Не используйте строки, символы и функции «T», если только вы не собираетесь выполнять сборки как в Юникоде, так и в ANSI. Если вы собираетесь создавать только Unicode-сборки, просто используйте обычные широкие символы: L "моя широкая строка" wcslen (L "моя строка") и т. Д.
1800 ИНФОРМАЦИЯ
Согласитесь, используйте макросы _T только в том случае, если вам нужен общий текст, то есть возможность кодирования как для Unicode, так и для Ascii / MBCS.
1
Если вы хотите использовать как Unicode, так и ANSI для строк C ++, используйте что-то вроде typedef std :: basic_string <TCHAR> tString;
Serge
Ах да, я всегда делаю #ifdef _UNICODE #define tstring std :: wstring #else #define tstring std :: string #endif, но мне больше нравится твой способ, Серж.
Адам Пирс
4
Честно говоря, я считаю, что UTF16 - бесполезная трата, оставляя все кодировки в UTF8 проще и более совместимыми с * nix.
chacham15
3

Посмотрите на сравнение строк без учета регистра в C ++

В этом вопросе есть ссылка на документацию Microsoft по Unicode: http://msdn.microsoft.com/en-us/library/cc194799.aspx

Если вы посмотрите на левую навигационную часть MSDN рядом с этой статьей, вы должны найти много информации, относящейся к функциям Unicode. Это часть главы «Кодирование символов» ( http://msdn.microsoft.com/en-us/library/cc194786.aspx )

Он состоит из следующих подразделов:

  • Модель кодовой страницы
  • Наборы двухбайтовых символов в Windows
  • Unicode
  • Проблемы совместимости в смешанных средах
  • Преобразование данных Unicode
  • Миграция программ для Windows в Unicode
  • Резюме
ине
источник
2

Хотя это может быть не лучшим решением для всех, вы можете написать свои собственные процедуры C ++ UNICODE, если хотите!

Я только что закончил делать это на выходных. Я многому научился, хотя я не гарантирую, что он на 100% свободен от ошибок, я провел много тестов, и, похоже, он работает правильно.

Мой код находится под новой лицензией BSD, и его можно найти здесь:

http://code.google.com/p/netwidecc/downloads/list

Он называется WSUCONV и поставляется с образцом программы main (), которая выполняет преобразование между UTF-8, UTF-16 и стандартным ASCII. Если выбросить основной код, у вас есть хорошая библиотека для чтения / записи UNICODE.

Уиллоу Шлангер
источник
1

Как было сказано выше, библиотека - лучший выбор при использовании большой системы. Однако иногда вы действительно хотите справиться с вещами самостоятельно (возможно, потому, что библиотека будет использовать многие ресурсы, например, на микроконтроллере). В этом случае вам нужна простая библиотека, из которой вы можете копировать части для вещей, которые вам действительно нужны.

Пример кода Уиллоу Шлангер кажется хорошим (подробнее см. Его ответ).

Я также нашел еще один, который имеет меньший код, но не имеет полной проверки ошибок и обрабатывает только UTF-8, но из него проще извлекать части.

Вот список встроенных библиотек, которые кажутся достойными.

Встроенные библиотеки

Пол Хатчинсон
источник