Lecture de caractères hors ASCII
Question
Un de mes amis m'a montré une situation où la lecture de personnages produisait un comportement inattendu. La lecture du caractère '¤' a provoqué le blocage de son programme. J'ai pu conclure que "¤" correspond à 164 décimales, donc il dépasse la plage ASCII.
Nous avons remarqué le comportement sur '¤' mais tout caractère & 127 semble indiquer le problème. La question est de savoir comment pouvons-nous lire de manière fiable de tels caractères, caractère par caractère?
int main(int argc, const char *argv[])
{
char input;
do
{
cin >> input;
cout << input;
cout << " " << setbase(10) << (int)input;
cout << " 0x" << setbase(16) << (int)input;
cout << endl;
} while(input);
return 0;
}
masse@libre:temp/2009-11-30 $ ./a.out
¤
 -62 0xffffffc2
¤ -92 0xffffffa4
La solution
Votre système utilise le codage de caractères UTF-8 (comme il se doit), donc le caractère '& # 164;' oblige votre programme à lire la séquence d'octets C2 A4
. Comme char
est un octet, il les lit un à la fois. Regardez dans le wchar_t
et les flux wcin
et wcout
correspondants pour lire les caractères multi-octets, bien que je ne sache pas quels codages ils supportent ni comment ils jouer avec les paramètres régionaux.
De plus, votre programme génère une sortie UTF-8 non valide. Par conséquent, vous ne devriez vraiment pas voir ces deux caractères & # 8212; Je reçois des points d'interrogation sur mon système.
(Ceci est un nitpick et un peu décalé, mais votre tant que (entrée)
doit être tant que (cin)
, sinon vous obtiendrez une boucle infinie.)
Autres conseils
Il est difficile de dire pourquoi le programme de votre ami se bloque sans afficher le code, mais cela peut être dû au fait que vous utilisez le caractère en tant qu'index dans un tableau. Étant donné que les caractères situés en dehors de la plage ASCII normale dépasseront la limite d'un caractère signé, le caractère deviendra négatif.
déclare plutôt 'entrée' comme caractère non signé