c++ - ¿Cómo funciona el soporte UTF-8 de TinyXML?
unicode (3)
Estoy usando TinyXML para analizar / compilar archivos XML. Ahora, según la documentación, esta biblioteca admite conjuntos de caracteres multibyte a través de UTF-8. Hasta ahora todo bien, creo. Pero, la única API que proporciona la biblioteca (para obtener / configurar nombres de elementos, nombres y valores de atributos, ... todo en donde se usa una cadena) es a través de std::string
o const char*
. Esto me hace dudar de mi propia comprensión del soporte de conjunto de caracteres multibyte. ¿Cómo puede una cadena que solo admite caracteres de 8 bits contener un carácter de 16 bits (a menos que use una página de códigos, lo que negaría la afirmación ''admite Unicode'')? Entiendo que en teoría podría tomar un punto de código de 16 bits y dividirlo en 2 caracteres en una std::string
, pero eso no transformaría la std::string
en una std::string
''Unicode'', lo haría inválido para la mayoría de los propósitos y tal vez funcione accidentalmente cuando se escribe en un archivo y se lee en otro programa.
Entonces, ¿alguien puede explicarme cómo una biblioteca puede ofrecer una ''interfaz de 8 bits'' ( std::string
o const char*
) y aún admite cadenas ''Unicode''?
(Probablemente confundí un poco la terminología de Unicode aquí, lo siento por cualquier confusión que surja de eso).
Al usar entre 1 y 4 caracteres para codificar un punto de código Unicode.
UTF-8 es compatible con el código ASCII de 7 bits. Si el valor de un byte es mayor que 127, significa que se inicia un carácter multibyte. Dependiendo del valor del primer byte, puede ver cuántos bytes tomará el personaje, que pueden ser de 2 a 4 bytes, incluido el primer byte (también son posibles 5 o 6, pero no son válidos para utf-8). Aquí hay un buen recurso sobre UTF-8: UTF-8 y Unicode FAQ , también la página wiki para utf8 es muy informativa. Como UTF-8 está basado en caracteres y terminado en 0, puede usar las funciones de cadenas estándar para la mayoría de las cosas. Lo único importante es que el recuento de caracteres puede diferir del recuento de bytes. Funciones como strlen () devuelven el recuento de bytes pero no necesariamente el recuento de caracteres.
Primero, utf-8 se almacena en cadenas const char *, como dijo @quinmars. Y no es solo un superconjunto de ASCII de 7 bits (puntos de código <= 127 codificados siempre en un solo byte como ellos mismos), además es cuidadoso de que los bytes con esos valores nunca se usen como parte de la codificación de los valores de multibyte para los puntos de código > = 128. Entonces, si ve un byte == 44, es un carácter ''<'', etc. Todos los metacaracteres en XML están en ASCII de 7 bits. Así que uno puede simplemente analizar el XML, rompiendo cadenas donde los metacars dicen, pegando los fragmentos (posiblemente incluyendo caracteres no ASCII) en un char * o std :: string, y los fragmentos devueltos siguen siendo cadenas UTF-8 válidas aunque el analizador no conocía específicamente UTF-8.
Además (no específico para XML, pero bastante inteligente), incluso cosas más complejas genralmente simplemente funcionan (tm). Por ejemplo, si clasifica UTF-8 lexicográficamente por bytes, obtiene la misma respuesta que clasificarlo lexicográficamente por puntos de código, a pesar de la variación en # de bytes utilizados, porque el prefijo bytes introduce el código más largo (y por lo tanto más valioso) los puntos son numéricamente mayores que aquellos para valores menores).