Перепутанный станд. C++:: wstring, UTF-16, UTF-8 и отображающиеся строки в окна GUI

Я работаю над английской только программой C++ для Windows, где нам говорили "всегда станд. использования:: wstring", но это ни на кого не походит в команде, действительно имеет большую часть понимания кроме того.

Я уже считал вопрос, названный "станд.:: wstring станд. VS:: строка. Это было очень полезно, но я все еще не вполне понимаю, как применить всю ту информацию к моей проблеме.

Программа я работаю над данными дисплеев в Windows GUI. Те данные сохраняются как XML. Мы часто преобразовываем это XML, использующий XSLT в HTML или XSL:FO для создания отчетов о целях.

Мое чувство на основе того, что я считал, состоит в том, что HTML должен быть закодирован как UTF-8. Я знаю очень мало о разработке GUI, но немного я читал, указывает, что материал GUI, все на основе UTF-16 закодировало строки.

Я пытаюсь понять, где это оставляет меня. Скажите, что мы решаем, что все наши сохраненные данные должны быть закодированным XML UTF-8. Это означает, что для отображения, сохранил данные в компоненте UI, я должен действительно выполнять своего рода явный UTF-8 к UTF-16, транскодирующему процесс?

Я подозреваю, что мое объяснение могло использовать разъяснение, таким образом, я попытаюсь обеспечить это, если у Вас будут какие-либо вопросы.

17
задан Community 23 May 2017 в 11:54
поделиться

5 ответов

Windows, начиная с NT4, основана на строках в кодировке Unicode, да. Ранние версии были основаны на UCS-2, который является предшественником UTF-16, и поэтому не поддерживает все символы, которые поддерживает UTF-16. Более поздние версии основаны на UTF-16. Однако не все операционные системы основаны на UTF-16 / UCS-2. Например, системы * nix основаны на UTF-8.

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

Да, вам нужно будет проанализировать XML, извлечь из него необходимую информацию, декодировать и преобразовать ее во что-то, что может использовать пользовательский интерфейс.

9
ответ дан 30 November 2019 в 13:12
поделиться

AFAIK, когда вы работаете с std :: wstring в Windows на C ++ и сохраняете файлы с использованием UTF-8 (что звучит хорошо и разумно), тогда вам нужно преобразовать данные в UTF-8 при записи в файл, и конвертировать обратно в UTF-16 при чтении из файла. Посмотрите эту ссылку: Написание файлов UTF-8 на C ++ .

Я бы придерживался значения Visual Studio по умолчанию для проекта -> Свойства -> Свойства конфигурации -> Общие -> Набор символов -> Использовать набор символов Юникода, использовать тип wchar_t (т.е. с std :: wstring) и не использовать тип TCHAR. (Например, я бы просто использовал версию strlen wcslen и , а не _tcslen.)

6
ответ дан 30 November 2019 в 13:12
поделиться

Даже если вы говорите, что в ваших данных используется только английский язык, вы, вероятно, ошибаетесь. Поскольку сейчас мы живем в глобальном мире, имена / адреса и т. Д. Содержат иностранные символы. Хорошо, я не знаю, какой тип данных у вас есть, но в целом я бы сказал, что создайте свое приложение для поддержки UNICODE как для хранения данных, так и для отображения данных пользователю. Это предполагает использование XML с UTF-8 для хранения и версий UNICODE вызовов Windows, когда вы выполняете GUI. А поскольку графический интерфейс Windows использует UTF-16, где каждый токен 16-битный, я бы предложил хранить данные в приложении в 16-битной строке. И я предполагаю, что ваш компилятор для Windows будет иметь std :: wstring как 16-битный только для этой цели.

Значит, вам нужно много конвертировать между UTF-16 и UTF-8. Сделайте это с помощью какой-нибудь существующей библиотеки, например, ICU .

1
ответ дан 30 November 2019 в 13:12
поделиться

Одно из преимуществ использования std :: wstring в Windows для строк, связанных с графическим интерфейсом пользователя, заключается в том, что все внутренние вызовы Windows API используют и работают с UTF-16. Если вы когда-нибудь замечали, есть 2 версии всех вызовов Win32 API, которые принимают строковые аргументы.Например, MessageBoxA и MessageBoxW. Оба определения существуют в, и на самом деле вы можете вызывать любое из них, но если они включены с включенной поддержкой Unicode, то произойдет следующее:

#define MessageBox MessageBoxW

Затем вы попадете в TCHAR и другие уловки Microsoft, чтобы попытаться упростить работу с API, которые имеют версии ANSI и Unicode. Короче говоря, вы можете вызвать любой, но под капотом ядро ​​Windows на основе Unicode, поэтому вы будете платить стоимость преобразования в Unicode для каждой строки, принимающей вызов Win32 API, если вы не используете версию с расширенными символами.

Использование UTF-16 и ядра Windows

3
ответ дан 30 November 2019 в 13:12
поделиться

std :: wstring технически является UCS-2: два байта используются для каждого символа, а кодовые таблицы в основном отображаются в формате Unicode. Важно понимать, что UCS-2 - это не то же самое, что UTF-16! UTF-16 позволяет использовать «суррогатные пары» для представления символов, выходящих за пределы двухбайтового диапазона, но UCS-2 использует ровно два байта для каждого символа, точки.

Лучшее правило для вашей ситуации - выполнять перекодировку при чтении и записи на диск. Как только он окажется в памяти, сохраните его в формате UCS-2. API-интерфейсы Windows будут читать его, как если бы это был UTF-16 (то есть, в то время как std :: wstring не понимает концепцию суррогатных пар, если вы создаете их вручную (чего вы не сделаете, если ваш единственный язык Английский), Windows их прочитает).

Каждый раз, когда вы читаете данные в форматах сериализации или из них (например, XML) в наши дни, вам, вероятно, потребуется выполнить перекодирование. Это неприятный и очень печальный факт жизни, но неизбежный, поскольку Unicode - это кодировка символов переменной ширины, а большинство символьных операций в C ++ выполняются в виде массивов, для которых вам нужен постоянный интервал.

Фреймворки более высокого уровня, такие как .NET, скрывают большую часть деталей, но за кулисами они обрабатывают перекодирование одним и тем же способом: изменяют данные переменной ширины на строки фиксированной ширины, манипулируют ими и затем изменяя их обратно в кодировки переменной ширины, когда это необходимо для вывода.

6
ответ дан 30 November 2019 в 13:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: