mbstowcs()
et wcstombs()
n'ont pas nécessairement convertir en UTF-16 ou UTF-32, ils convertir wchar_t
, et quelle que soit la locale wchar_t
encodage. Tous les paramètres régionaux Windows utilise deux octets wchar_t
et UTF-16 comme le codage, mais les autres grandes plates-formes utilisent un 4 octets wchar_t
avec de l'UTF-32 (ou même un non-codage Unicode pour certains endroits). Une plate-forme qui prend en charge uniquement un octet codages pourrait même avoir un seul octet wchar_t
et ont l'encodage diffèrent par les paramètres régionaux. Donc, wchar_t
me semble être un mauvais choix pour la portabilité et Unicode. *
Certains de meilleures options ont été introduits dans C++11; de nouvelles spécialisations de std::codecvt, de nouvelles codecvt classes, et un nouveau modèle pour rendre leur utilisation pour les conversions très pratique.
Première de la nouvelle classe de modèle pour l'utilisation de codecvt est std::wstring_convert. Une fois que vous avez créé une instance d'un std::wstring_convert classe, vous pouvez convertir facilement entre les chaînes:
std::wstring_convert<...> convert; // ... filled in with a codecvt to do UTF-8 <-> UTF-16
std::string utf8_string = u8"This string has UTF-8 content";
std::u16string utf16_string = convert.from_bytes(utf8_string);
std::string another_utf8_string = convert.to_bytes(utf16_string);
Pour faire différentes conversion, vous avez juste besoin de différents paramètres du modèle, dont l'un est une facette codecvt. Voici de nouvelles facettes qui sont faciles à utiliser avec wstring_convert:
std::codecvt_utf8_utf16<char16_t> // converts between UTF-8 <-> UTF-16
std::codecvt_utf8<char32_t> // converts between UTF-8 <-> UTF-32
std::codecvt_utf8<char16_t> // converts between UTF-8 <-> UCS-2 (warning, not UTF-16! Don't bother using this one)
Exemples d'utilisation de ces:
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>,char16_t> convert;
std::string a = convert.to_bytes(u"This string has UTF-16 content");
std::u16string b = convert.from_bytes(u8"blah blah blah");
La nouvelle std::codecvt spécialisations sont un peu plus difficiles à utiliser car ils ont protégé destructeur. Pour obtenir autour de ce que vous pouvez définir une sous-classe qui a un destructeur, ou vous pouvez utiliser les std::use_facet fonction de modèle pour obtenir un existant codecvt instance. Aussi, un problème avec ces spécialisations est que vous ne pouvez pas les utiliser dans Visual Studio 2010 en raison de spécialisation de modèle ne fonctionne pas avec typedef avais types et que le compilateur définit char16_t et char32_t que les typedefs. Voici un exemple de la définition de votre propre sous-classe de codecvt:
template <class internT, class externT, class stateT>
struct codecvt : std::codecvt<internT,externT,stateT>
{ ~codecvt(){} };
std::wstring_convert<codecvt<char16_t,char,std::mbstate_t>,char16_t> convert16;
std::wstring_convert<codecvt<char32_t,char,std::mbstate_t>,char32_t> convert32;
Le char16_t spécialisation convertit entre le format UTF-16 et UTF-8. Le char32_t spécialisation, UTF-32 et UTF-8.
Notez que ces nouvelles conversions prévues par le C++11 ne comprennent pas de toute façon de convertir directement entre UTF-32 et UTF-16. Au lieu de cela il vous suffit de combiner les deux instances de std::wstring_convert.
* Je pensais que je voudrais ajouter une note sur wchar_t et de son objectif, à souligner pourquoi il ne doit généralement pas être utilisé pour l'Unicode ou portable internationalisés code. Ce qui suit est une version courte de ma réponse http://stackoverflow.com/a/11107667/365496
Qu'est-ce que wchar_t?
wchar_t est définie de telle façon que tous les paramètres régionaux de l'encodage peut être converti wchar_t où tous les wchar_t représente exactement une codepoint:
Type wchar_t est un type distinct dont les valeurs peuvent représenter des codes distincts pour tous les membres de la plus grande étendue de caractère spécifié parmi les paramètres régionaux pris en charge (22.3.1). -- [de base.fondamentaux] 3.9.1/5
Ce n'est pas exiger que wchar_t être suffisamment grand pour représenter tous les caractères de toutes les langues simultanément. Qui est, le codage utilisé pour les wchar_t peuvent différer entre les paramètres régionaux. Ce qui signifie que vous ne pouvez pas nécessairement convertir une chaîne de wchar_t à l'aide de l'un des paramètres régionaux et ensuite de les convertir en arrière de l'omble à l'aide d'une autre région.
Depuis qui semble être la principale utilisation dans la pratique pour wchar_t vous pourriez vous demander ce que c'est bon pour si pas que.
L'original de l'intention et le but de wchar_t était de faire du traitement de texte simple en le définissant telle qu'elle nécessite un one-to-one mapping à partir d'une chaîne de code-parts pour le texte des personnages, permettant ainsi l'utilisation de simples algorithmes utilisés avec des chaînes ascii de travailler avec d'autres langues.
Malheureusement, les exigences sur wchar_t assumer un one-to-one mapping entre les personnages et codepoints pour atteindre cet objectif. Unicode des pauses d'une hypothèse, de sorte que vous ne pouvez pas l'utiliser en toute sécurité wchar_t pour du texte simple, des algorithmes de soit.
Cela signifie que le logiciel portable ne peut pas utiliser wchar_t soit comme une représentation commune pour le texte entre les paramètres régionaux, ou à permettre l'utilisation de texte simple des algorithmes.
Quel est wchar_t aujourd'hui?
Pas beaucoup, pour un code portable, de toute façon. Si __STDC_ISO_10646__
est défini, les valeurs de wchar_t représentent directement Unicode codepoints avec les mêmes valeurs dans tous les lieux. Que fait-il sécuritaire de faire de l'inter-régionaux des conversions mentionné plus tôt. Cependant, vous ne pouvez pas compter uniquement sur elle de décider que vous pouvez utiliser wchar_t de cette façon parce que, bien que la plupart des plates-formes unix définir, Windows n'a pas même si Windows utilise le même wchar_t locale dans toutes les régions.
La raison pour Windows ne définit __STDC_ISO_10646__
je crois, à cause de Windows utiliser l'UTF-16 comme son wchar_t de codage, et parce que UTF-16 utilise des paires de substitution pour représenter codepoints plus grand que U+FFFF, ce qui signifie que UTF-16 n'est pas satisfait aux exigences pour l' __STDC_ISO_10646__
.
Pour la plate-forme de code spécifique wchar_t peut-être plus utile. Il est essentiellement nécessaire sur Windows (par exemple, certains fichiers ne peuvent simplement pas être ouvert sans l'aide de wchar_t les noms de fichiers), si Windows est la seule plate-forme où cela est vrai pour autant que je sais (donc peut-être que nous pouvons penser de wchar_t comme "Windows_char_t').
Avec le recul, wchar_t est clairement pas utile pour simplifier le traitement de texte, ou comme stockage pour les paramètres régionaux de texte indépendant. Code Portable ne devrait pas tenter de l'utiliser à ces fins.