189 votes

Dans quelle mesure Unicode est-il pris en charge en C ++11?

J'ai lu et entendu que C ++ 11 prend en charge Unicode. Quelques questions à ce sujet:

  • Dans quelle mesure la bibliothèque standard C ++ prend-elle en charge Unicode?
  • Est-ce que std::string fait ce qu’il devrait faire?
  • Comment puis-je l'utiliser?
  • Où sont les problèmes potentiels?

275voto

R. Martinho Fernandes Points 96873

Comment bien le C++ standard library support de l'unicode?

Terriblement.

Une analyse rapide à travers les installations de la bibliothèque qui pourrait fournir le support de l'Unicode me donne cette liste:

  • Les chaînes de la bibliothèque
  • La localisation de la bibliothèque
  • D'entrée/sortie de la bibliothèque
  • Les expressions régulières de la bibliothèque

Je pense que tous, mais le premier de fournir terrible de soutien. Je vais y revenir plus en détail après un rapide détour par le biais de vos autres questions.

N' std::string ce qu'il devrait?

Oui. Selon la norme C++, c'est ce qu' std::string et de ses frères et sœurs devraient faire:

Le modèle de classe basic_string décrit des objets qui peuvent stocker une séquence composée d'un nombre variable de l'arbitraire char comme des objets avec le premier élément de la séquence à la position zéro.

Eh bien, std::string le fait très bien. Le fait de fournir Unicode fonctionnalités spécifiques? Pas de.

Devrait-il? Probablement pas. std::string est fine comme une séquence de char objets. C'est utile; le seul ennui, c'est que c'est un très faible niveau de l'affichage de texte et de la norme C++ n'est pas de fournir un niveau supérieur.

Comment puis-je l'utiliser?

L'utiliser comme une séquence de char objets; prétendant que c'est quelque chose d'autre est lié à la fin dans la douleur.

Où sont les problèmes potentiels?

Tous sur la place? Voyons voir...

Les chaînes de la bibliothèque

Les chaînes de la bibliothèque nous fournit basic_string, qui est simplement une séquence de ce que la norme appelle "char comme des objets". Je les appelle des unités de code. Si vous voulez une vue de haut niveau du texte, ce n'est pas ce que vous cherchez. Ceci est une vue de texte approprié pour la sérialisation/désérialisation/de stockage.

Il fournit également des outils de la bibliothèque C qui peuvent être utilisés pour combler le fossé entre l'étroitesse du monde et de l'Unicode monde: c16rtomb/mbrtoc16 et c32rtomb/mbrtoc32.

La localisation de la bibliothèque

La localisation de la bibliothèque croit encore que l'un de ces "char comme des objets" équivaut à un "caractère". C'est bien sûr ridicule, et il est impossible d'obtenir beaucoup de choses à travailler correctement au-delà d'un petit sous-ensemble de l'Unicode en ASCII par exemple.

Considérons, par exemple, ce que la norme appelle "la commodité des interfaces" dans l' <locale> - tête:

template <class charT> bool isspace (charT c, const locale& loc);
template <class charT> bool isprint (charT c, const locale& loc);
template <class charT> bool iscntrl (charT c, const locale& loc);
// ...
template <class charT> charT toupper(charT c, const locale& loc);
template <class charT> charT tolower(charT c, const locale& loc);
// ...

Comment voulez-vous que l'une de ces fonctions pour bien classer, disons, U+1F34C ʙᴀɴᴀɴᴀ, en u8"

41voto

Matthieu M. Points 101624

Unicode n'est pas pris en charge par la Bibliothèque Standard (pour toute raisonnable sens de la prise en charge).

std::string n'est pas meilleur qu' std::vector<char>: c'est complètement inconscient Unicode (ou toute autre représentation/encodage) et se contentent de traiter son contenu comme une goutte d'octets.

Si vous avez seulement besoin de stocker et de catenate gouttes, cela fonctionne assez bien; mais dès que vous le souhaitez pour la fonctionnalité Unicode (nombre de points de code, le nombre de graphèmes, ...), vous êtes hors de la chance.

La seule bibliothèque complète je connais pour ce qui est de l'ICU. L'interface C++ a été dérivée à partir du code Java, donc c'est loin d'être idiomatiques.

26voto

uckelman Points 7228

Vous pouvez stocker en toute sécurité UTF-8 std::string (ou char[] ou char*), en raison du fait qu'un caractère NUL (U+0000) est un octet nul en UTF-8 et que c'est la seule manière d'un octet null peut se produire en UTF-8. Par conséquent, votre des chaînes UTF-8 sera terminée correctement en fonction de toutes les C et C++ les fonctions de chaîne, et vous pouvez écharpe autour du C++ iostreams (y compris std::cout et std::cerr, aussi longtemps que votre locale UTF-8).

Ce que vous ne pouvez pas faire avec std::string pour l'UTF-8 est d'obtenir la longueur de points de code. std::string::size() va vous dire la longueur de la chaîne en octets, qui est seulement égal au nombre de points de code lorsque vous êtes à l'intérieur de l'ASCII sous-ensemble de l'UTF-8.

Si vous avez besoin pour fonctionner sur des chaînes UTF-8 sur le point de code de niveau---pas seulement de stocker et de les imprimer---ou si vous faites affaire avec de l'UTF-16, qui est susceptible d'avoir à l'interne, plusieurs octets nuls, vous avez besoin de regarder dans la chaîne de caractères larges types.

8voto

Joachim Pileborg Points 121221

C ++11 a un couple de nouveaux types de chaîne littérale pour Unicode.

Malheureusement, la prise en charge dans la bibliothèque standard pour les encodages non uniforme (comme UTF-8) est encore mal. Par exemple il n’y a aucun moyen de nice pour obtenir la longueur (en points de code) d’une chaîne UTF-8.

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