Использование UTF в коде C ++ - PullRequest
6 голосов
/ 14 октября 2008

В чем разница между UTF и UCS.

Каковы наилучшие способы представления неевропейских наборов символов (с использованием UTF) в строках C ++. Я хотел бы знать ваши рекомендации для:

  • Внутреннее представление внутри кода
    • Для работы со строками во время выполнения
    • Для использования строки в целях отображения.
  • Наилучшее представление хранилища ( т.е. В файле)
  • Лучший формат передачи по проводной сети (передача между приложениями, которые могут быть на разных архитектурах и иметь разные стандартные локали)

Ответы [ 5 ]

8 голосов
/ 14 октября 2008

В чем разница между UTF и UCS.

Кодировки UCS имеют фиксированную ширину и отмечены количеством байтов, используемых для каждого символа. Например, UCS-2 требует 2 байта на символ. Символы с кодовыми точками за пределами доступного диапазона не могут быть закодированы в кодировке UCS.

Кодировки UTF имеют переменную ширину и отмечены минимальным количеством битов для хранения символа. Например, UTF-16 требует по меньшей мере 16 бит (2 байта) на символ. Символы с большими кодовыми точками кодируются с использованием большего количества байтов - 4 байта для астральных символов в UTF-16.

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

Для современных систем наиболее приемлемым кодированием хранения и транспорта является UTF-8. Существуют особые случаи, когда могут подойти другие - UTF-7 для старых почтовых серверов, UTF-16 для плохо написанных текстовых редакторов - но UTF-8 является наиболее распространенным.

Предпочтительное внутреннее представление будет зависеть от вашей платформы. В Windows это UTF-16. В UNIX это UCS-4. У каждого есть свои плюсы:

  • Строки UTF-16 никогда не используют больше памяти, чем строка UCS-4. Если вы храните много больших строк с символами в основном в базовой многоязычной плоскости (BMP), UTF-16 потребует гораздо меньше места, чем UCS-4. За пределами BMP он будет использовать ту же сумму.
  • UCS-4 легче рассуждать. Поскольку символы UTF-16 могут быть разделены на несколько «суррогатных пар», может возникнуть проблема с правильным разделением или отображением строки. Текст UCS-4 не имеет этой проблемы. UCS-4 также действует подобно тексту ASCII в массивах "char", поэтому существующие текстовые алгоритмы могут быть легко перенесены.

Наконец, некоторые системы используют UTF-8 в качестве внутреннего формата. Это хорошо, если вам нужно взаимодействовать с существующими системами на основе ASCII или ISO-8859, поскольку байты NULL отсутствуют в середине текста UTF-8 - они есть в UTF-16 или UCS-4.

2 голосов
/ 14 октября 2008

Я бы предложил:

  • Для представления в коде, wchar_t или эквивалент.
  • Для представления хранилища, UTF-8.
  • Для представления проводов, UTF-8.

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

0 голосов
/ 14 октября 2008

Во внутреннем представлении внутри кода лучше сделать это для европейских и неевропейских символов:

\ uNNNN

Символы в диапазоне от \ u0020 до EE и небольшой пробел (например, конец строки) могут быть записаны как обычные символы. Все, что выше \ u0080, если вы напишите его как обычный символ, оно будет скомпилировано только на вашей кодовой странице (например, «Хорошо во Франции, но в России, в России, в Японии, в Китае, в США и т. Д.»). .).

0 голосов
/ 14 октября 2008

UTC - это Всемирное координированное время, а не набор символов (я не нашел ни одной кодировки под названием UTC).

Для внутреннего представления вы можете использовать wchar_t для каждого символа и std :: wstring для строк. Они используют ровно 2 байта для каждого символа, поэтому поиск и произвольный доступ будут быстрыми.

Для хранения, если большая часть данных не является ASCII (т.е. код> = 128), вы можете использовать UTF-16, который почти совпадает с сериализованными wstring и wchar_t.

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

...