Glossaire Unicode
Unicode est un vaste et complexe sujet. Je ne souhaite pas wade trop profonde il y a, cependant, un rapide glossaire est nécessaire:
-
Les Points de Code: les Points de Code sont les blocs de construction de base de l'Unicode, un point de code est juste un entier mappé à un sens. La partie entière s'adapte en 32 bits (bien, 24 bits vraiment), et le sens peut être une lettre, un signe diacritique, un espace, un signe, un smiley, une demi-drapeau, ... et il peut même être "la prochaine partie se lit de droite à gauche".
-
Graphème Clusters: Graphème les Clusters sont des groupes d'sémantiquement liées Points de Code, par exemple un drapeau dans unicode est représentée par l'association de deux Points de Code; chacun de ces deux, dans l'isolement, n'a pas de sens, mais associées dans un Graphème Cluster ils représentent un drapeau. Graphème Clusters sont également utilisés pour paire une lettre avec un signe diacritique dans certains scripts.
C'est la base de la norme Unicode. La distinction entre le Point de Code et de Graphème Cluster peut être principalement passées sous silence parce que pour la plupart des langues modernes chaque "personnage" est mappé à un seul Point de Code (il y a dédié accentué les formes les plus couramment utilisées lettre+diacritique combinaisons). Encore, si vous vous aventurez dans des smileys, des drapeaux, etc... alors vous pourriez avoir à payer l'attention sur la distinction.
UTF Apprêt
Ensuite, une série de Points de Code Unicode doit être codé; la commune encodage est UTF-8, UTF-16 et UTF-32, les deux derniers existant dans les deux Little-Endian et Big-Endian formes, pour un total de 5 communes encodages.
En UTF-X, où X est la taille en bits de l' Unité de Code, chaque Point de Code est représenté par une ou plusieurs Unités de Code, en fonction de son ampleur:
- UTF-8: 1 à 4 Unités de Code,
- UTF-16: 1 ou 2 Unités de Code,
- UTF-32: 1 Code Unité.
std::string
et std::wstring
.
- Ne pas utiliser
std::wstring
si vous vous souciez de la portabilité (wchar_t
seulement 16 bits sur Windows); utilisation std::u32string
à la place (aka std::basic_string<char32_t>
).
- La représentation en mémoire (
std::string
ou std::wstring
) est indépendant de la sur-disque représentation (UTF-8, UTF-16 ou UTF-32), alors préparez-vous pour avoir à les convertir à la limite (lecture et écriture).
- Alors qu'un 32 bits
wchar_t
assure qu'une Unité de Code représente le Point de Code, il n'est toujours pas représenter une complète Graphème Cluster.
Si vous êtes seulement de la lecture ou de la composition des chaînes, vous ne devriez pas avoir de problèmes peu avec std::string
ou std::wstring
.
Les ennuis commencent lorsque vous commencez à découper et couper en dés, alors vous devez faire attention à (1) du Code frontières (en UTF-8 ou UTF-16) et (2) de Graphème Clusters limites. L'ancien peut être traitée assez facilement sur votre propre, ce dernier nécessite l'utilisation de l'Unicode conscient de la bibliothèque.
La cueillette std::string
ou std::u32string
?
Si la performance est une préoccupation, il est probable qu' std::string
ont un meilleur rendement en raison de sa plus petite empreinte mémoire; si un usage intensif de Chinois peut changer la donne. Comme toujours, profil.
Si Graphème les Clusters ne sont pas un problème, std::u32string
a l'avantage de simplifier les choses: 1 Unité de Code -> 1 Point de Code signifie que vous ne pouvez pas accidentellement divisé Points de Code, et toutes les fonctions de l' std::basic_string
travaillent hors de la boîte.
Si vous interface avec les logiciels prenant std::string
ou char*
/char const*
, puis de s'y tenir std::string
pour éviter les va-et-vient des conversions. Ça va être une douleur autrement.
UTF-8 std::string
.
UTF-8 fonctionne très bien, en std::string
.
La plupart des opérations de travail hors de la boîte, car le codage UTF-8 est l'auto-synchronisation et de l'arrière-compatible avec l'ASCII.
En raison de la façon dont les Points de Code sont codés à la recherche d'un Point de Code ne peut pas accidentellement match au milieu d'un autre Point de Code:
-
str.find('\n')
de travaux,
-
str.find("...")
travaux pour la mise en correspondance se fait octet par octet1,
-
str.find_first_of("\r\n")
fonctionne si la recherche de caractères ASCII.
De même, regex
doit surtout fonctionne hors de la boîte. Comme une séquence de caractères ("haha"
) est juste une séquence d'octets ("哈"
), habitudes de recherche de base doit travailler hors de la boîte.
Méfiez-vous, cependant, de classes de caractères (comme [:alphanum:]
), car selon l'expression rationnelle de la saveur et de la mise en œuvre, il peut ou peut ne pas correspondre à des caractères Unicode.
De même, méfiez-vous de l'application des répétiteurs pour les non-ASCII "caractères", "哈?"
peut considérer que le dernier octet pour être facultatif; utiliser des parenthèses pour délimiter clairement la répétition de la séquence d'octets dans de tels cas: "(哈)?"
.
1Les concepts clés de recherche sont la normalisation et de classement; cela affecte toutes les opérations de comparaison. std::string
toujours comparer (et donc de tri) octet par octet, sans égard pour la comparaison des règles spécifiques à une langue ou d'une utilisation. Si vous devez gérer la normalisation/classement, vous avez besoin d'un complet Unicode de la bibliothèque, tels que les unités de soins intensifs.