2008-09-28 5 views
12

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

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

(Я, вероятно, перепутал терминологию Юникода здесь, извините за любую путаницу, исходящую от этого).

ответ

8

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

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

+0

Хорошо, спасибо, это становится понятнее, но затем - используя std :: string для представления данных UTF-8 таким образом, разве это не семантически неправильно? Вы никогда не сможете полагаться на содержимое этой строки - даже не будет способа узнать, как долго это будет! (длина символа). – Roel 2008-09-29 06:38:54

2

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

0

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

 Смежные вопросы

  • Нет связанных вопросов^_^