Использование UTF в коде C++

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

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

  • Внутреннее представление внутри кода
    • Для манипулирования строками во время выполнения
    • Для использования строки в целях отображения.
  • Лучшее представление хранилища (т.е. в файле)
  • Лучший формат для проводного транспорта (передача между приложениями, которые могут быть на разных архитектурах и иметь другой стандартный языковой стандарт)
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
6
0
1 518
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

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

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

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

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

Размер wchar_t (а следовательно, и внутри wstring) не определен. Я видел как 2-х, так и 4-х байтовые версии. Почему UTS-16 для хранения, а UTF-8 для файлов (файлы могут быть сохранены на одной машине и загружены на другую). Я хочу понять, почему вы сделали этот выбор так же, как и выбор.

Martin York 14.10.2008 10:18

@Martin: UTF-16 не может быть обработан существующими инструментами, ориентированными на ASCII, потому что многие байты равны 0, что заставляет побайтовые функции полагать, что достигнут нулевой терминатор.

John Millikin 14.10.2008 19:42

Я бы посоветовал:

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

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

wchar_t: а какая кодировка? Вы предлагаете UTF-16 для внутреннего использования?

Martin York 14.10.2008 10:14

На многих платформах Unix wchar_t составляет 32 бита, так что это легко. На платформах, где wchar_t - 16 бит, да, UTF-16 будет подходящим вариантом.

Chris Jester-Young 14.10.2008 10:24

Мартин: Я откатил ваше редактирование, потому что использование wchar_t не подразумевает UTF-16 - в UNIX sizeof (wchar_t) == 4.

John Millikin 14.10.2008 10:39

Честно говоря, это была плохая правка. Но wchar_t может содержать «кодовую точку» UTF-16, а wchar_t не имеет подразумеваемого представления, поэтому вы можете хранить в нем любую кодировку (если позволяет размер). Итак, я ищу, как мне хранить строку внутри для манипуляций и отображения?

Martin York 14.10.2008 11:05

Смотрите мой ответ: используйте все, что используется на вашей платформе. Windows: UTF-16. UNIX: UCS-4. Используемый тип данных является случайным, в любом случае это просто typedef.

John Millikin 14.10.2008 11:12

Использование UTF-32 в качестве внутреннего хранилища (например, в некоторых разновидностях Unix) - ужасная трата памяти, и это не рекомендуется стандартом Unicode.

Nemanja Trifunovic 14.10.2008 17:52

Вы читали статью Джоэла Спольски о Абсолютный минимум. Каждый разработчик программного обеспечения должен абсолютно точно знать о Unicode и наборах символов (без оправданий!)?

Это и многое другое. Но мне нужны мнения более чем одного человека, чтобы понять, что происходит в отраслевом кодексе.

Martin York 14.10.2008 10:14
Ответ принят как подходящий

What is the difference between UTF and UCS.

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

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

  • Internal representation inside the code
  • Best storage representation (i.e. In file)
  • Best on wire transport format (Transfer between application that may be on different architectures and have a different standard locale)

Для современных систем наиболее разумной кодировкой хранения и транспорта является 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.

Нет, кодировки UTF не всегда имеют переменную ширину (например, подумайте о UTF-32).

bortzmeyer 14.10.2008 11:53

Utf-32 может использовать фиксированную ширину для каждой кодовой точки, но считать у вас все еще может быть (и вам нужно принять и нормализовать до одной кодовой точки) несколько кодовых точек (когда у вас есть объединение символов), которые представляют один полный символ / глиф. Если это так, UTF-32 не намного лучше, чем UTF-16.

Shadow2531 14.10.2008 18:19

@bortzmeyer: UTF-32 - это просто UCS-4 с некоторыми дополнительными ограничениями. Честно говоря, я никогда не видел, чтобы UTF-32 использовал везде, поэтому я просто игнорирую его.

John Millikin 14.10.2008 19:40

Тень: объединение символов на самом деле не проблема, если вы не пишете средство визуализации текста, в то время как суррогатные пары UTF-16 означают, что для символов все требуется специальный код обработки.

John Millikin 14.10.2008 19:45

@John Millikin: Я считаю, что UTF-32 используется в большинстве современных систем Linux (в отличие от UTF-16, используемого в Windows).

Head Geek 14.10.2008 23:07

@Head Geek: Linux может поддерживать UTF-32, но изначально использует UTF-8 (в отличие от собственного использования UTF-16 в Windows). cl.cam.ac.uk/~mgk25/unicode.html

sean e 19.06.2009 23:33

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

\ uNNNN

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

Другие вопросы по теме