Question

Disclaimer : Mes excuses pour tout le texte ci-dessous (pour une seule question simple), mais je pense sincèrement que chaque bit d'information est pertinente à la question. Je serais heureux d'apprendre autrement. Je ne peux qu'espérer que, en cas de succès, la question (s) et les réponses peuvent aider les autres dans la folie Unicode. Ici va.

J'ai lu tous les sites habituellement hautement considérés sur UTF8, en particulier

Était-ce utile?

La solution

Ok, donc votre problème ici est due au mélange des appels de bibliothèque à l'ancienne école C (getc, printf% c) et UTF-8. Votre code est en train de lire correctement les trois octets qui composent « € » - 226, 130 et 172 en décimal - mais ces valeurs sont individuellement pas UTF-8 valides Glyphes codées.

Si vous regardez le encodage UTF-8 , des valeurs entières 0 ..127 sont les encodages pour l'ensemble original de caractères US-ASCII. Cependant 128..255 (à savoir tous vos octets) font partie d'un jeu de caractères UTF-8 multi-octets, et donc ne correspondent pas à un UTF-8 valide le caractère individuellement au moyen.

En d'autres termes, le seul octet « 226 » ne veut pas dire quoi que ce soit sur son propre (comme il est le préfixe d'un caractère de 3 octets - comme prévu). Les impressions d'appel printf comme un seul octet, qui est non valide avec le codage UTF-8, de sorte que chaque autre programme fait face à la valeur non valide de différentes manières.

En supposant que vous voulez juste « voir » ce que les octets de caractères UTF-8 est fait, je vous suggère de coller à la sortie entier que vous avez déjà (ou peut-être utiliser hex si cela est plus sensible) - comme> 127 octets arn « t unicode valide, vous avez peu de chances d'obtenir des résultats cohérents entre les différents programmes.

Autres conseils

L'encodage UTF-8 indique que les trois octets ensemble dans une chaîne forment le signe euro, ou '€. Mais les octets, comme ceux produits par votre programme C, n'a pas de sens dans un flux UTF-8. C'est pourquoi ils sont remplacés par le U + FFFD « CARACTÈRE DE REMPLACEMENT » ou « ».

E-macs est intelligent, il sait que les octets simples sont des données non valides pour le flux de sortie, et le remplace par une représentation d'échappement visible de l'octet. sortie Mousepad est vraiment cassé, je ne peux pas faire de sens. Tapis de souris tombe retour à la page de code CP1252 de Windows, où les octets individuels représentent des personnages. La « virgule » n'est pas une virgule, il est un bas citation courbe.

La première chose que vous avez publié:

Character: � Integer: 226
Character: �, Integer: 130
Character: �, Integer: 172

La réponse est « correcte ». Lorsque vous imprimez le caractère 226 et le terminal s'attend UTF8, il n'y a rien que le terminal peut faire, vous a donné des données non valides. La séquence « 226 » « espace » est une erreur. Le ? caractère est une belle façon de vous montrer qu'il ya quelque part des données malformé.

Si vous souhaitez répliquer votre deuxième exemple, vous devez encoder correctement le caractère.

Imaginez deux fonctions; décodage, ce qui prend un codage de caractères et un flux d'octets et produit une liste de caractères; et encoder, ce qui prend un codage d'une liste de caractères et produit un flux d'octets. encode / decode doit être réversible lorsque vos données est valide. encode ( 'utf8', decode ( 'utf8', "...")) == "..."

Quoi qu'il en soit, dans le second exemple, l'application ( « tapis de souris? ») Est le traitement de chaque octet dans la représentation de trois octets du caractère euro comme un caractère latin1 individuel. Il obtient l'octet, décode du latin-1 à une représentation interne d'un « caractère » (non l'octet ou octet), et code alors que le caractère UTF8 et écrit que le terminal. Voilà pourquoi cela fonctionne.

Si vous avez GNU Recode, essayez ceci:

$ recode latin1..utf8
<three-octet representation of the euro character> <control-D>
â¬

Ce que cela a été traiter chaque octet de la représentation utf-8 comme un caractère latin1, puis converti chacun de ces personnages en quelque chose que votre terminal peut comprendre. Peut-être en cours d'exécution à travers ce HD rend plus claire:

$ cat | hd
€
00000000  e2 82 ac 0a               |....|
00000004

Comme vous pouvez le voir, il est 3 octets pour la représentation utf-8 du caractère, puis un retour à la ligne.

Traversant recodage:

$ recode latin1..utf8 | hd
€
00000000  c3 a2 c2 82 c2 ac 0a      |.......|
00000007

est la représentation utf-8 de la chaîne d'entrée « latin1 »; quelque chose que votre terminal peut afficher. L'idée est que si vous émettez à votre terminal, vous verrez le signe euro. Si vous émettez, vous obtenez rien, ce n'est pas valide. Enfin, si vous émettez, vous obtenez la « poubelle » qui est la « représentation utf-8 » du caractère.

Si cela semble confondre est. Vous ne devriez jamais vous soucier de la représentation interne comme celui-ci; si vous travaillez avec des personnages et vous avez besoin de les imprimer à un terminal utf-8, vous devez toujours encoder à utf-8. Si vous lisez à partir d'un fichier codé utf-8, vous devez décoder les octets en caractères avant de les traiter dans votre application.

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