chez mon entreprise, nous avons une bibliothèque de plate-forme transversale (Linux & Windows) contenant notre propre extension de la STL STD :: String, cette classe fournit toutes sortes de fonctionnalités au-dessus de la chaîne; Split, format, to / depuis base64, etc. Récemment, nous avons reçu l'obligation de faire cette chaîne unicode "amical" fondamentalement, il doit soutenir des personnages de chinois, japonais, arabe, etc. Après la recherche initiale, cela semble bien sur le côté Linux Comme tout est intrinsèquement utf-8, mais je rencontre des problèmes avec le côté Windows; Y a-t-il un tour pour obtenir la STL STD :: String pour travailler comme UTF-8 sur Windows? Est-ce même possible? Y a-t-il une meilleure façon? Idéalement, nous resterions nous-mêmes basé sur la STD :: String car c'est ce que la classe de chaîne est basée sur Linux. P>
Merci, P>
9 Réponses :
Avez-vous regardé std :: wstring code>? C'est une version de
std :: basique_string code> pour
wchar_t code> plutôt que le
char code> que
std :: string code> utilise. < / p>
Ce n'est pas la même chose que Unicode sur Windows..ethwing n'a pas de soutien réel dans la STL ..
Mettre en place des points de code UTF-8 dans un std :: string code> devrait aller bien quelle que soit la plate-forme. Le problème sous Windows est que presque rien d'autre n'attend ou ne fonctionne pas avec UTF-8 - il attend et fonctionne avec UTF-16. Vous pouvez passer à un
std :: wstring code> qui stockera UTF-16 (au moins sur la plupart des compilateurs Windows) ou vous pouvez écrire d'autres routines qui accepteront UTF-8 (probablement en convertissant à l'UTF-16 , puis passant à travers le système d'exploitation). P>
Essayé d'utiliser Wstring, mais l'application semble être incapable de rendre les caractères Unicode que je testais avec, "大夨 天太夫", donc pas sûr de quoi faire de cela? Y a-t-il des fenêtres spéciales "Voodoo" que je dois travailler pour que Wstring fonctionne pour travailler?
@Nsa, vous devez sélectionner une police qui inclut les caractères que vous souhaitez afficher. Très peu de polices ont une grande partie des points de code Unicode couverts.
@NSA - Assurez-vous que "Support de langues Est" activé dans le panneau de contrôle -> Paramètres régionaux et linguistiques. Vous pouvez également utiliser une police qui manque ces caractères.
@NSA: Cela dépend. Si vous essayez d'utiliser cout code> ou
wcout code>, c'est à peu près une catastrophe. Si vous passez le contenu d'un
wstring code> directement sur une fonction Windows, les choses sont beaucoup plus simples (
printf code> et un tel travail aussi). À partir de là, il s'agit principalement d'assurer que la police que vous utilisez peut afficher tous les caractères que vous aimez.
Il y a plusieurs idées fausses dans votre question. P>
ni c ++ ni l'affaire STL avec les codages. p> li>
linux est pas em> intrinsèquement utf-8. La plupart des distributions sont de nos jours par défaut de l'UTF-8, mais il ne faut pas s'appuyer sur. P> Li>
ul> std :: string code> est essentiellement une chaîne de octets em>, pas caractères em>. Donc, vous ne devriez pas avoir de problème de farce UTF-8 encodé unicode. Toutefois, gardez à l'esprit que toutes les fonctions code> string code> fonctionnent également sur des octets, donc
mystring.length () code> vous donnera le nombre d'octets et non le nombre de caractères. p> li>
Si STL ne connaît rien de codages, qu'est-ce que STD :: locale alors?
Lieu. Qui n'est pas la même chose que le codage.
Mais le nom de la locale peut contenir le nom d'un codage, par ex. EN_US-UTF8, donc il me semble faux de dire "STL ne sait pas rien i> sur les codages".
@Paniq: std :: locale code> appartient au côté code> iOSTream code> de la bibliothèque standard, pas du côté STL de la bibliothèque standard.
STD :: String Code> n'a pas démarré comme une classe STL, mais a été faite de type STL lorsque la STL a été ajoutée au projet C ++ 98 (en 1996).
Non, il n'ya aucun moyen de traiter Windows Traiter des chaînes "étroites" comme UTF-8. P>
Voici ce qui fonctionne le mieux pour moi dans cette situation (application multi-plateformes contenant des bâtiments Windows et Linux). P>
Autres approches que j'ai essayées mais n'aime pas beaucoup: p>
TypeDEF STD :: basique_string TString; code> utilise ensuite TString dans le code d'entreprise. Les enveloppes / surcharges peuvent être faites pour rationaliser la conversion entre STD :: String et STD :: TString, mais il ajoute toujours beaucoup de douleur. Li>
- Utilisez
std :: wstring code> partout. N'ajoute pas beaucoup depuis wchar_t code> 16 bits sous Windows, vous devez donc vous limiter à vous limiter à BMP ou à accéder à de nombreuses complications pour rendre le code traite avec une plate-forme multiples Unicode. Dans ce dernier cas, tous les avantages sur UTF-8 s'évaporent. LI>
- Utilisez ATL / WTL / MFC
CSSTRING CODE> dans la partie spécifique à la platine; Utilisez std :: chaîne code> dans la partie transversale. C'est en fait une variante de ce que je recommande ci-dessus. cstring code> est dans de nombreux aspects supérieurs à std :: string code> (à mon avis). Mais il introduit une dépendance supplémentaire et donc pas toujours acceptable ou commode. Li>
ul>
Utiliser STD :: Wstring ne vous limite pas à la BMP. La gamme complète de points de codes Unicode peut être codée dans UTF-16, en utilisant des substituts, le cas échéant, et STD :: Wstring peut contenir une chaîne codée UTF-16.
@Remy - Bien sûr. C'est ce que je voulais dire par «ou aller à beaucoup de complications pour rendre le code traitant de la plate-forme continue Unicode». Sur Linux, wchar_t peut contenir tout le code de code de code; Sous Windows, il ne peut pas. Vous devez donc utiliser la compilation conditionnelle et les trucs. Et vous n'avez plus la belle propriété de "une cellule == un caractère" plus. Alors pourquoi pas seulement utiliser UTF-8?
Essayez std :: basic_string
@Remy - Je n'ai jamais impliqué qu'il y a une garantie "une cellule = une Char" dans UTF-8. S'il vous plaît lire plus attentivement. Utilisation de std :: basic_string
Si vous voulez éviter les maux de tête, n'utilisez pas du tout les types de chaîne stl. C ++ sait rien sur Unicode ou des codages, afin d'être portable, il est préférable d'utiliser une bibliothèque adaptée au support Unicode, par exemple. la bibliothèque ICU. L'ICU utilise des chaînes UTF-16 par défaut, donc aucune conversion n'est requise et prend en charge les conversions vers de nombreux autres codages importants tels que UTF-8. Essayez également d'utiliser des bibliothèques inter-plateformes telles que Boost.FileSystem pour des choses comme des manipulations de chemin ( boost :: wpath code>). Évitez
std :: string code> et
std :: FRStream code>. P>
dans la bibliothèque d'exécution de Windows API et C, Je suis dans une situation similaire, étant au milieu du logiciel de portage de Windows à Linux tout en le faisant savoir unicode. L'approche que nous avons prise est: p>
Ceci est également L'approche POCO a pris . P> PARAMETERS DE CHAR * CODE> est interprété comme encodé dans la page "ANSI". Le problème est que UF-8 n'est pas pris en charge comme une page de code ANSI a>, qui Je trouve incroyablement ennuyeux . p>
UTF-8 est partiellement supporté en tant que page de code ANSI et s'appelle Windows CP65001. Il a des problèmes qui ne sont pas encore repassés, bien que comme un bogue dans le fichier Wrystfile () code> API.
Oui - en étant plus conscient des locaux et des codages. P>
Windows a deux appels de fonctions pour tout ce qui nécessite un texte, un Foobara () et un Foobarw (). Les fonctions * W () prennent des chaînes codées UTF-16, le * A () prend des chaînes dans le codépage actuel. Toutefois, Windows ne prend pas en charge une page de code UTF-8, vous ne pouvez donc pas l'utiliser directement dans ce sens avec les fonctions * A () et ne voudriez pas dépendre de celle-ci par les utilisateurs. Si vous souhaitez "Unicode" sous Windows, utilisez les fonctions UNICODE-CAPABLE (* W). Il y a des tutoriels là-bas, Googling "Unicode Windows Tutorial" devrait vous en obtenir. P>
Si vous stockez des données UTF-8 dans une STD :: String, puis avant de la transmettre à Windows, convertissez-la en UTF-16 (Windows fournit des fonctions pour le faire), puis transmettez-la à Windows. < / p>
Beaucoup de ces problèmes découlent de C / C ++ étant généralement encodés-agnostiques. Certaines personnes ont recommandé qui est un type d'entier dont la plage de valeurs peut représenter des codes distincts pour tous les membres du plus grand jeu de caractères étendu spécifié parmi les locaux pris en charge P>
blockQuote>
in Linux, un Char code> n'est pas vraiment un personnage, c'est juste un type intégral. Même en utilisant des tableaux code> Char code> pour stocker les données UTF-8, vous pouvez vous mettre en difficulté si vous devez accéder aux unités de code individuelles, car
Char code> SIGNÉ-NESS est laissé non défini par le normes. Une déclaration comme
str [x] <0x80 code> pour vérifier que les caractères de plusieurs octets peuvent introduire rapidement un bug. (Cette déclaration est toujours vraie si
Char code> est signé.) Une unité de code UTF-8 est un type intégré non signé avec une plage de 0 à 255. Cette carte vers le type C de
uint8_t code> exactement, bien que
non signé Char code> fonctionne également. Idéalement, je ferais une chaîne UTF-8 une chaîne de
uint8_t code> s, mais en raison d'anciennes API, ceci est rarement fait. P>
wchar_t code>, réclamant qu'il s'agit d'être "un type de caractère unicode" ou quelque chose comme ça. Encore une fois, la norme est tout aussi agnostique qu'auparavant, car c est censé travailler n'importe où et n'importe où pourrait ne pas utiliser Unicode. Ainsi,
wchar_t code> n'est plus unicode que
char code>. Les états standard: p>
wchart_t code> représente une unité de code / code de code UTF-32. C'est donc 4 octets. Cependant, sous Windows, c'est une unité de code UTF-16 et n'est que 2 octets. (Ce qui, j'aurais dit que je ne serais pas conforme à ce qui précède, car 2 octets ne peuvent pas représenter tous d'unicode, mais c'est ainsi que cela fonctionne.) Cette différence de taille et la différence de codage de données, met clairement une souche sur la portabilité. La norme UNICODE elle-même recommande contre
wchar_t code> si vous avez besoin de portabilité. (§5.2) p>
Il dépend vraiment de la plate-forme, Unicode est mal à la tête. Dépend du compilateur que vous utilisez. Pour les plus anciens de la SP (VS2010 ou plus), vous auriez besoin d'une API d'utilisation décrite dans MSDN
pour VS2015 P>
std::string _old = u8"D:\\Folder\\This \xe2\x80\x93 by ABC.txt"; std::cout << _old.data();
Vous devez envisager d'utiliser qstring et qbytearray, il a un bon support unicode p>
Voir cette question, a une réponse très approfondie: Stackoverflow.com/Questtions/402283 / stdwstring-vs-stdstring
Mai ou peut ne pas aider (ne peut pas le tester moi-même): SetLocale (LC_CTYPE, "EN_US.UTF-8") cplusplus.com/reference/clibrary/clocale/setlocale Cela définit le codage pour l'ensemble de l'application à UTF-8
Regardez ma réponse ici: