Вопрос

я использую КрошечныйXML для анализа/сборки XML-файлов.Теперь, согласно документация эта библиотека поддерживает многобайтовые наборы символов через UTF-8.Думаю, пока все хорошо.Но единственный API, который предоставляет библиотека (для получения/установки имен элементов, имен и значений атрибутов,...все, где используется строка) проходит через std::string или const char*.Это заставляет меня усомниться в моем собственном понимании поддержки многобайтового набора символов.Как может строка, поддерживающая только 8-битные символы, содержать 16-битный символ (если только она не использует кодовую страницу, которая опровергнет утверждение «поддерживает Unicode»)?Я понимаю, что теоретически вы могли бы взять 16-битную кодовую точку и разделить ее на 2 символа в std::string, но это не изменит std::string в строку «Unicode», это сделает ее недействительной для большинства целей и, возможно, случайно сработает при записи в файл и чтении другой программой.

Итак, может ли кто-нибудь объяснить мне, как библиотека может предлагать «8-битный интерфейс» (std::string или const char*) и по-прежнему поддерживаете строки Unicode?

(Вероятно, я перепутал здесь терминологию Unicode;извините за возникшую путаницу).

Это было полезно?

Решение

Во-первых, как сказал @quinmars, utf-8 хранится в строках const char *.И это не только расширенный набор 7-битного ASCII (кодовые точки <= 127 всегда кодируются в одном байте как таковые), но и более того, байты с этими значениями никогда не используются как часть кодирования многобайтовых значений для кодовых точек. >= 128.Итак, если вы видите байт == 44, это символ «<» и т. д.Все метасимволы в XML представлены в 7-битном формате ASCII.Таким образом, можно просто проанализировать XML, разбивая строки там, где это указано в метасимволах, вставляя фрагменты (возможно, включая символы, отличные от ASCII) в char * или std::string, и возвращаемые фрагменты остаются действительными строками UTF-8, даже если парсер конкретно не знал UTF-8.

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

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

UTF-8 совместим с 7-битным кодом ASCII.Если значение байта больше 127, это означает, что начинается многобайтовый символ.В зависимости от значения первого байта вы можете увидеть, сколько байт займет символ, это может быть 2-4 байта, включая первый байт (технически возможны также 5 или 6, но они не действительны для utf-8).Вот хороший ресурс о UTF-8: Часто задаваемые вопросы по UTF-8 и Unicode, также вики-страница для utf8 очень информативна.Поскольку UTF-8 основан на символах и заканчивается 0, вы можете использовать стандартные строковые функции для большинства вещей.Единственное, что важно, это то, что количество символов может отличаться от количества байтов.Такие функции, как strlen(), возвращают количество байтов, но не обязательно количество символов.

Используя от 1 до 4 символов для кодирования одной кодовой точки Unicode.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top