Question

J'utilise TinyXML pour analyser / créer des fichiers XML. Désormais, selon la documentation , cette bibliothèque prend en charge les jeux de caractères multi-octets via UTF-8. Jusqu'ici tout va bien je pense. Cependant, la seule API fournie par la bibliothèque (pour obtenir / définir les noms d'éléments, les noms d'attributs et les valeurs, ... tout ce pour quoi une chaîne est utilisée) est via std::string ou const char*. Cela me fait douter de ma propre compréhension du support des jeux de caractères multi-octets. Comment une chaîne qui ne prend en charge que les caractères 8 bits peut-elle contenir un caractère 16 bits (à moins d'utiliser une page de code qui annulerait la revendication 'prend en charge la définition Unicode')? Je comprends que vous pouvez théoriquement prendre un point de code 16 bits et le scinder en deux caractères dans un <=>, mais cela ne transformerait pas le <=> en une chaîne 'Unicode', cela le rendrait non valide pour la plupart des cas. et fonctionnerait peut-être accidentellement s’il était écrit dans un fichier et lu par un autre programme.

Alors, quelqu'un peut-il m'expliquer comment une bibliothèque peut offrir une "interface 8 bits" (<=> ou <=>) tout en prenant en charge les chaînes "Unicode"?

(J'ai probablement confondu la terminologie Unicode ici; désolé de toute confusion résultant de cela).

Était-ce utile?

La solution

Tout d’abord, utf-8 est stocké dans des chaînes const char *, comme le dit @quinmars. Et ce n'est pas seulement un sur-ensemble d'ASCII 7 bits (points de code & Lt; = 127 toujours codés dans un seul octet), il faut également veiller à ce que les octets avec ces valeurs ne soient jamais utilisés dans le codage du multibyte valeurs pour les points de code > = 128. Donc, si vous voyez un octet == 44, il s'agit d'un '<' caractère, etc. Tous les métacars de XML sont en ASCII 7 bits. Il suffit donc d’analyser le code XML, en séparant les chaînes à la place des métachars, en collant les fragments (y compris éventuellement des caractères non ASCII) dans un char * ou std :: string, et les fragments renvoyés restent des chaînes UTF-8 valides même si le analyseur ne connaissait pas spécifiquement UTF-8.

Plus loin (pas spécifique à XML, mais plutôt intelligent), des choses encore plus complexes fonctionnent généralement bien (tm). Par exemple, si vous triez UTF-8 lexicographiquement par octets, vous obtenez la même réponse que si vous triiez lexicographiquement par points de code, malgré la variation du nombre d'octets utilisés, car le préfixe introduisant le code plus long (et donc plus élevé) les points sont numériquement supérieurs à ceux des valeurs inférieures).

Autres conseils

UTF-8 est compatible avec le code ASCII 7 bits. Si la valeur d'un octet est supérieure à 127, cela signifie qu'un caractère multi-octets commence. En fonction de la valeur du premier octet, vous pouvez voir le nombre d'octets que prendra le caractère, ce qui peut représenter 2 à 4 octets, y compris le premier octet (5 ou 6 techniques sont également possibles, mais elles ne sont pas valides. Utf-8). Voici une bonne ressource sur UTF-8: FAQ sur UTF-8 et Unicode , la page wiki pour utf8 est également très informative. Étant donné que UTF-8 est basé sur un caractère et que sa terminaison est 0, vous pouvez utiliser les fonctions de chaîne standard pour la plupart des choses. La seule chose importante est que le nombre de caractères peut différer du nombre d'octets. Des fonctions comme strlen () renvoient le nombre d'octets mais pas nécessairement le nombre de caractères.

En utilisant entre 1 et 4 caractères pour coder un point de code Unicode.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top