2009-11-24 10 views
0

Je travaille sur une petite application C++ qui gère un peu la chaîne. Actuellement, je veux extraire une chaîne à un index de caractères particulier. Ma solution naïve d'utiliser la méthode at() de chaîne fonctionne bien, mais elle casse pour les chaînes non-ascii. Par exemple:Index de caractères de chaîne non-ASCII en C++

string test = "ヘ(^_^ヘ)(ノ^_^)ノ" 
cout << test.at(0) << endl; 

Produit un signe dièse en sortie pour moi sous gcc 4.2. Je ne pense pas non plus que ce soit un problème avec mon terminal, parce que je peux très bien imprimer toute la chaîne. Y at-il une bibliothèque ou quelque chose que je pourrais utiliser pour obtenir l'effet désiré?

Répondre

2

string utilise char s qui sont seulement 8 bits. Vous devez utiliser wstring si vous souhaitez coder des caractères 16 bits.

+0

Et 'std :: wcout' – GManNickG

1

Votre chaîne est probablement UTF-8, où "caractères" et "octets" ne sont pas la même chose. La classe std::string suppose que les "caractères" ont chacun un octet, donc les résultats sont faux.

Vos options sont à convertir la chaîne en UTF-16 et d'utiliser un lieu wstring, où vous pouvez (généralement) supposer que les caractères sont tous deux octets chacun (un wchar_t ou short) ou vous pouvez utiliser une bibliothèque comme ICU ou UTF8-CPP pour opérer directement sur des chaînes UTF-8, en faisant des choses comme "obtenir le 3ème caractère" plutôt que "obtenir le 3ème octet". Ou, si vous voulez aller minimaliste, vous pouvez simplement coder une fonction (relativement) simple pour obtenir le décalage d'octets et la longueur d'un caractère particulier en réutilisant les fonctions internes de l'une des fonctions de longueur de chaîne UTF-8 d'une des bibliothèques listées ci-dessus ou de google. Fondamentalement, vous devez inspecter chaque caractère et sauter 1-3 octets pour arriver au début du caractère suivant en fonction des bits qui sont définis.

est ici qui pourrait facilement se traduire à partir de PHP:

for($i = 0; $i < strlen($str); $i++) { 
    $value = ord($str[$i]); 
    if($value > 127) { 
     if($value >= 192 && $value <= 223) 
      $i++; 
     elseif($value >= 224 && $value <= 239) 
      $i = $i + 2; 
     elseif($value >= 240 && $value <= 247) 
      $i = $i + 3; 
     else 
      die('Not a UTF-8 compatible string'); 
     } 
    $count++; 
} 

http://www.php.net/manual/en/function.strlen.php#25715

Questions connexes