L'obtention de la longueur réelle d'une codé en UTF-8 std::string?
mon std::string est codé en utf-8 alors, évidemment, str.length() renvoie le résultat erroné.
J'ai trouvé cette information, mais je ne suis pas sûr de savoir comment je peux l'utiliser pour ce faire:
L'octet suivant les séquences sont
utilisé pour représenter un caractère. L'
séquence
utilisé dépend de l'UCS, le numéro de code de caractère:0x00000000 - 0x0000007F: 0xxxxxxx 0x00000080 - 0x000007FF: 110xxxxx 10xxxxxx 0x00000800 - 0x0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx 0x00010000 - 0x001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
Comment puis-je trouver la longueur réelle d'une codé en UTF-8 std::string? Grâce
- C++ ne sait rien à propos de codage, de sorte que vous ne pouvez pas vous attendre à utiliser une fonction standard pour ce faire. Certains Systèmes d'Exploitation (par exemple, Windows) peut offrir des fonctions pour aider à cela, si vous ne voulez pas écrire un à partir de zéro.
- Je comprends que c'est pourquoi j'ai marqué ce également algorithme, je ne veux en écrire un à partir de zéro
- Veuillez noter que, bien que Michael réclamation est vrai quand il l'a écrit, depuis C++11 de la Bibliothèque Standard ne sais à propos de codages. Voir stackoverflow.com/questions/16863937/...
- Qu'entendez-vous par "durée réelle"? Nombre de points de code? Dans la NFC, NFD, NFKC, ou NFKD? Nombre de composite personnages? Nombre de graphèmes? Nombre de graphème clusters? Nombre de pixels sur l'écran dans une police donnée?
- En effet, la plupart des réponses ici supposent que la "longueur" signifie "nombre de points de code".
- Intéressant à lire: utf8everywhere.org/#myth.strlen
Vous devez vous connecter pour publier un commentaire.
L'un des projets que j'ai contribuer a une petite fonction qui fait que:
http://openlierox.git.sourceforge.net/git/gitweb.cgi?p=openlierox/openlierox;a=blob;f=include/Unicode.h;h=a523b464fc65a7ad875e683cd830b41c9a01934a;hb=HEAD
Recherchez
Utf8StringSize
. Il dépend d'une autre petite fonction dans le même fichier d'en-tête.Compter tous les premiers octets (ceux qui ne correspondent pas 10xxxxxx).
&
partie.De la bibliothèque standard en effet ne reconnaître l'existence d'encodages de caractères, sous la forme de paramètres régionaux. Si votre système prend en charge des paramètres régionaux, il est très facile à utiliser la bibliothèque standard pour calculer la longueur d'une chaîne. Dans l'exemple de code ci-dessous je suppose que votre système prend en charge la locale en_US.UTF-8. Si je compile le code et l'exécuter en tant que "./un.hors ソニーSony", la sortie est qu'il y avait 13 char-les valeurs et les 7 caractères. Et le tout sans aucune référence à la représentation interne de l'UTF-8 codes de caractères ou d'avoir à utiliser la 3ème partie des bibliothèques.
Vous devriez probablement prendre l'avis d'Omry et regardez-la dans une bibliothèque spécialisée pour cela. Cela dit, si vous voulez juste de comprendre l'algorithme pour ce faire, je vais le poster ci-dessous.
Fondamentalement, vous pouvez convertir une chaîne en un plus large-format de l'élément, comme
wchar_t
. Notez quewchar_t
a quelques problèmes de portabilité, carwchar_t
est de taille variable en fonction de votre plate-forme. Sur Windows,wchar_t
est de 2 octets, et donc idéal pour la représentation UTF-16. Mais sur UNIX/Linux, il est de quatre octets, et est donc utilisé pour représenter l'UTF-32. Par conséquent, pour Windows, cela ne fonctionnera que si vous n'incluez pas l'Unicode codepoints au-dessus de 0xFFFF. Pour Linux, vous pouvez inclure l'ensemble de la gamme de codepoints dans unwchar_t
. (Heureusement, ce problème sera atténué avec le C++0x Unicode types de caractères.)Avec cet avertissement noté, vous pouvez créer une fonction de conversion à l'aide de l'algorithme suivant:
L'algorithme n'est pas totalement générique, parce que le InputIterator doit être un unsigned char, de sorte que vous pouvez interpréter chaque octet comme ayant une valeur comprise entre 0 et 0xFF. Le OutputIterator est générique, (si vous pouvez utiliser un std::back_inserter et ne pas s'inquiéter de l'allocation de mémoire), mais son utilisation comme un paramètre générique est limitée: en gros, c'est à la sortie d'un tableau d'éléments suffisamment grand pour représenter un UTF-16 ou UTF-32 caractères, tels que
wchar_t
,uint32_t
ou le C++0xchar32_t
types. Aussi, je ne comprend pas le code pour convertir des caractères les séquences d'octets de plus de 4 octets, mais vous devriez obtenir le point de fonctionnement de l'algorithme à partir de ce qui est posté.Aussi, si vous voulez juste compter le nombre de caractères, plutôt que de la sortie d'un nouveau grand personnage de la mémoire tampon, vous pouvez modifier l'algorithme afin d'inclure un compteur, plutôt que sur une OutputIterator. Ou, mieux encore, il suffit d'utiliser Marcelo Cantos de réponse à compter de la première-octets.
\u
hexadécimal.C'est une implémentation naïve, mais il devrait être utile pour vous de voir comment c'est fait:
Je vous recommande d'utiliser UTF8-RPC. C'est un en-tête de la seule bibliothèque pour travailler avec de l'UTF-8 en C++. Avec cette lib, il ressemblerait à quelque chose comme ceci:
(Le Code est le sommet de ma tête.)
essayez d'utiliser une librairie d'encodage comme iconv.
c'est sans doute l'api que vous voulez.
une alternative est de mettre en place votre propre utf8strlen qui détermine la durée de chaque codepoint et de réitérer codepoints à la place des caractères.
UTF-8 CPP bibliothèque a une fonction qui ne fait que cela. Vous pouvez inclure la librairie dans votre projet (il est petit) ou tout simplement regarder la fonction. http://utfcpp.sourceforge.net/
Ce code je suis portage à partir de php-iconv pour c++, vous devez utiliser iconv d'abord, l'espoir utile:
Juste une autre implémentation naïve de compter les caractères dans la chaîne UTF-8
Un peu paresseux approche serait de ne compter que les octets avance, mais la visite de chaque octet. Cela permet d'économiser de la complexité de décodage quelques longueurs d'octets, mais évidemment, vous payer pour visiter tous les octets, même si, habituellement, ne sont pas si nombreux (2x-3x):
Noter que certaines valeurs de code sont illégaux en tant que responsable octets, ceux qui représentent les plus grandes valeurs que les 20 bits nécessaires pour unicode étendu, par exemple, mais alors l'autre approche serait de ne pas savoir comment traiter avec ce code, de toute façon.