Есть ли какие-либо опасности для внутренней работы в UTF-8 и последующего преобразования в UTF-16 только при необходимости в Windows? - PullRequest
4 голосов
/ 08 марта 2012

Visual Studio пытается настаивать на использовании tchars, который при компиляции с опцией UNICODE в итоге заканчивается использованием широких версий Windows и других API.

Существует ли тогда какая-либо опасность для использования UTF-8 внутри приложения (что упрощает использование C ++ STL, а также обеспечивает более читаемый кроссплатформенный код), а затем конвертирование в UTF-16 возможно только тогда, когда вам нужноиспользовать какой-либо из API-интерфейсов ОС?

Я специально спрашиваю о разработке для более чем одной ОС - Windows, которая не использует UTF-8, и других, таких как Mac, которые это делают.

Ответы [ 7 ]

2 голосов
/ 09 марта 2012

Как уже говорили другие, нет опасности использовать UTF-8 внутри, а затем конвертировать, когда вам нужно вызывать функции Windows.

Однако имейте в виду, что стоимость конвертации каждый раз может быть чрезмерно высокой, если вы отображаете много текста. (Помните, у вас есть не только преобразование, но вы также можете заплатить за выделение и освобождение буферов для хранения временных преобразованных строк.)

Я также должен отметить, что в STL встроена поддержка широких символов, так что на самом деле нет причин для этого. (std :: wstring и др.)

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

1 голос
/ 09 марта 2012

Если у вас есть ОС, в которой используются API-символы видимости (er), и вы пишете приложение, требующее поддержки интернационализации, глупо использовать char и UTF-8 в качестве внутреннего представления в вашей программе,Вы используете UTF-8 в обратном направлении.UTF-8 предназначен для контрабанды Unicode через интерфейсы операционных систем, а также форматы хранения и обмена данными, которые не могут напрямую обрабатывать широкие символы.

1 голос
/ 09 марта 2012

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

Но если ваш проект не сконцентрирован на обработке / манипулировании / преобразовании текста, то ограничение на UTF-8 на всех платформах не самое простое решение.

Избегайте использования char в Windows

Если вы работаете с типом char при разработке Windows, тогда все WinAPI будут использовать char.

Проблема в том, что тип char в Windowsиспользуется для «исторических» приложений, то есть до-Unicode-приложений.

Каждый текст char интерпретируется как текст не-Unicode, кодировка / кодировка которого выбирается пользователем Windows, а не пользователем.developper .

Значение: если вы считаете, что работаете с UTF-8, отправьте этот текст UTF-8 char в WinAPI для вывода в GUI (иTextBox и т. Д.), А затем выполните свой код в Windows, настроенной на арабском языке (например), и вы увидите, что ваш красивый символ UTF-8 не будет корректно обрабатываться WinAPI, потому что WinAPI в этой Windowsсчитает, что все char должны интерпретироваться как кодировка Windows-1256 .

Если вы работаете с char в Windows, вы отказываетесь от Unicode если каждый вызов WinAPI не проходит через перевод (обычно через Framework, такой как GTK +, QT и т. д., но это могут быть ваши собственные функции-оболочки).

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

Альтернатива: почему бы не использовать TCHAR навсе платформы?

Что вам нужно сделать, так это работать с TCHAR, предоставить заголовок, аналогичный tchar.h для Linux / MacOS / независимо от того, что (повторное выделение макросов и т. д. в исходном заголовке tchar.h),увеличивая этос tchar.h -подобным заголовком для объектов стандартной библиотеки, которые вы хотите использовать.Например, мой tstring.hpp выглядит так:

// tstring.hpp
#include <string>
#include <sstream>
#include <fstream>
#include <iostream>

#ifdef _MSC_VER
#include <tchar.h>
#include <windows.h>
#else
#ifdef __GNUC__
#include <MyProject/tchar_linux.h>
#endif // __GNUC__
#endif


namespace std
{

#ifdef _MSC_VER

   // On Windows, the exact type of TCHAR depends on the UNICODE and
   // _UNICODE macros. So the following is useful to complete the
   // tchar.h headers with the C++ Standard Library's symbols.

   #ifdef UNICODE

      typedef              wstring        tstring ;
      // etc.
      static wostream &    tcout          = wcout ;

   #else // #ifdef UNICODE

      typedef              string         tstring ;
      // etc.
      static ostream &     tcout          = cout ;

   #endif // #ifdef UNICODE

#else // #ifdef _MSC_VER

    #ifdef __GNUC__

    // On Linux, char is expected to be UTF-8 encoded, so the
    // following simply maps the txxxxx type into the xxxxx
    // type, forwaking the wxxxxx altogether.
    // Of course, your mileage will vary, but the basic idea is
    // there.

    typedef                string         tstring ;
    // etc.
    static ostream &       tcout          = cout ;

    #endif // __GNUC__

#endif // #ifdef _MSC_VER

} // namespace std

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

Используя эти заголовки, вы можете использовать Стандартную библиотеку C ++ в сочетании со средством TCHAR, то есть использовать std::tstring, который будет скомпилирован как std::wstring в Windows (при условии, что вы компилируете определения UNICODE и _UNICODE определений) и как std::string на других ОС на основе char, которые вы хотите поддерживать.

Таким образом, вы сможетеиспользуйте родной символьный тип платформы бесплатно.

Пока вы агностик с вашим типом символов TCHAR, проблем не будет.

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

Обычно это делается путем предоставленияперегрузки одной и той же функции для разных типов и для каждой ОС.Таким образом, правильная функция выбирается во время компиляции.

1 голос
/ 08 марта 2012

Поскольку UTF-8 и UTF-16 являются просто двумя способами кодирования чисел (которые затем интерпретируются как так называемые кодовые точки или глифы), нет ничего плохого в преобразовании назад и вперед: информация не теряется.Так что нет, в конвертации нет опасности (если, конечно, конвертация верна).

0 голосов
/ 07 мая 2012

Нет, нет опасности, если вы будете следовать указаниям. [1] На самом деле это самый разумный и простой путь, [2], даже если вы пишете для только для Windows .

И обратите внимание, что UTF-8 никогда дольше, чем UTF-16 для европейских языков,ни для не-BMP персонажей.Он занимает больше места только для кодовых точек, закодированных 3 байтами в UTF-8 и 2 в UTF-16, что в точности соответствует диапазону от U + 0800 до U + FFFF, [3] в основном это символы CJK.

0 голосов
/ 09 марта 2012

UTF-8 - это дикий и дурацкий способ представления персонажей.Вы должны избегать его использования везде, где это возможно.Windows API избегает UTF-8.(Если вы настаиваете на «многобайтовой» сборке, а не на сборке «юникод», она сделает все преобразования за вас, под прикрытием, поэтому она может продолжать использовать UTF16 - и если вы не будете осторожны, неэффективность всех этихскрытые преобразования сожрут вас.) Библиотека wxWidgets избегает UTF-8 таким же образом, и это кросс-платформенный с MAC.

Вы должны принять подсказку и избегать UTF-8 самостоятельно.

Когда вам нужно использовать UTF-8?Проблема с UTF16 состоит в том, что это зависит от порядка байтов в словах, реализованных в оборудовании.Поэтому при передаче данных между разными компьютерами, которые могут использовать другой порядок байтов на своем оборудовании, вы должны использовать UTF8, который имеет одинаковый порядок байтов на любом оборудовании.Вот почему браузеры и WWW-страницы используют UTF8.

0 голосов
/ 08 марта 2012

«Опасность» заключается в том, что количество символов в кодировке UTF-8 отличается от количества символов в кодировке ASCII. Например, U + 24B62 - это один символ Unicode, но расширяется до 4 байтов UTF-8. (См. здесь для других примеров.)

Если вы не используете их взаимозаменяемо, все будет в порядке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...