6 votes

Comment mesurer la taille correcte des caractères non-ASCII ?

Dans le programme suivant, j'essaie de mesurer la longueur d'une chaîne de caractères non ASCII.

Mais, je ne suis pas sûr de savoir pourquoi le size() n'imprime pas la longueur correcte lorsqu'il utilise des caractères non ASCII.

#include <iostream>
#include <string>

int main()
{
    std::string s1 = "Hello";
    std::string s2 = "इंडिया"; // non-ASCII string
    std::cout << "Size of " << s1 << " is " << s1.size() << std::endl;
    std::cout << "Size of " << s2 << " is " << s2.size() << std::endl;
}

Sortie :

Size of Hello is 5
Size of इंडिया is 18

Démonstration en direct Boîte à baguettes .

4voto

cbuchart Points 91

std::string::size renvoie la longueur en octets, et non en nombre de caractères. Votre deuxième chaîne de caractères utilise un encodage UNICODE, il se peut donc qu'elle prenne plusieurs octets par caractère. Notez qu'il en va de même pour std::wstring::size car il dépendra de l'encodage (il renvoie le nombre de caractères larges, pas les caractères réels : si UTF-16 est utilisé, il correspondra mais pas nécessairement pour d'autres encodages, plus dans cette réponse ).

Pour mesurer la longueur réelle (en nombre de symboles), vous devez connaître le codage afin de séparer (et donc de compter) les caractères correctement. Cette réponse peut être utile pour UTF-8 par exemple (bien que la méthode utilisée soit dépréciée dans C++17).

Une autre option pour UTF-8 est de compter le nombre de premiers octets ( crédit à cette autre réponse ):

int utf8_length(const std::string& s) {
  int len = 0;
  for (auto c : s)
      len += (c & 0xc0) != 0x80;
  return len;
}

1voto

Rxmsc Points 927

J'ai utilisé std::wstring_convert et a obtenu la longueur correcte des chaînes de caractères.

#include <string>
#include <iostream>
#include <codecvt>

int main()
{
    std::string s1 = "Hello";
    std::string s2 = "इंडिया"; // non-ASCII string
    std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> cn;
    auto sz = cn.from_bytes(s2).size();
    std::cout << "Size of " << s2 << " is " << sz << std::endl;
}

Démonstration en direct Boîte à baguettes .

Lien de référence d'importance ici pour en savoir plus sur std::wstring_convert

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X