La question est de savoir comment convertir wstring en chaîne?
J'ai l'exemple suivant:
#include <string>
#include <iostream>
int main()
{
std::wstring ws = L"Hello";
std::string s( ws.begin(), ws.end() );
//std::cout <<"std::string = "<<s<<std::endl;
std::wcout<<"std::wstring = "<<ws<<std::endl;
std::cout <<"std::string = "<<s<<std::endl;
}
la sortie avec la ligne commentée est:
std::string = Hello
std::wstring = Hello
std::string = Hello
mais sans c'est seulement:
std::wstring = Hello
Quelque chose ne va pas dans l'exemple? Puis-je faire la conversion comme ci-dessus?
ÉDITER
Un nouvel exemple (en tenant compte de certaines réponses) est
#include <string>
#include <iostream>
#include <sstream>
#include <locale>
int main()
{
setlocale(LC_CTYPE, "");
const std::wstring ws = L"Hello";
const std::string s( ws.begin(), ws.end() );
std::cout<<"std::string = "<<s<<std::endl;
std::wcout<<"std::wstring = "<<ws<<std::endl;
std::stringstream ss;
ss << ws.c_str();
std::cout<<"std::stringstream = "<<ss.str()<<std::endl;
}
La sortie est:
std::string = Hello
std::wstring = Hello
std::stringstream = 0x860283c
par conséquent, le flux de chaînes ne peut pas être utilisé pour convertir wstring en chaîne.
std::wstring
du tout? stackoverflow.com/questions/1049947/…Réponses:
Voici une solution élaborée basée sur les autres suggestions:
Cela fonctionnera généralement pour Linux, mais créera des problèmes sous Windows.
la source
std::setlocale(LC_ALL, "");
vraiment nécessaire?std::wcout.imbue(locale)
devrait également faire le travail, et elle a l'avantage de ne changer aucun état global.std::wstring_convert
C ++ 11 résume une grande partie de ce bruit.*** glibc detected *** test: malloc(): smallbin double linked list corrupted: 0x000000000180ea30 ***
sur Linux 64 bits (gcc 4.7.3). Quelqu'un d'autre vit ça?Comme Cubbi l'a souligné dans l'un des commentaires,
std::wstring_convert
(C ++ 11) fournit une solution simple et soignée (vous devez#include
<locale>
et<codecvt>
):J'utilisais une combinaison d'
wcstombs
allocation / désallocation fastidieuse de mémoire avant de tomber sur cela.http://en.cppreference.com/w/cpp/locale/wstring_convert
mise à jour (2013.11.28)
Un liners peut être déclaré ainsi (merci Guss pour votre commentaire):
Les fonctions d'encapsuleur peuvent être définies comme suit: (Merci ArmanSchwarz pour votre commentaire)
Remarque: il y a une certaine controverse quant à savoir si
string
/wstring
devrait être passé aux fonctions en tant que références ou en tant que littéraux (en raison de C ++ 11 et des mises à jour du compilateur). Je laisse la décision à la personne chargée de la mise en œuvre, mais cela vaut la peine de le savoir.Remarque: J'utilise
std::codecvt_utf8
dans le code ci-dessus, mais si vous n'utilisez pas UTF-8, vous devrez le changer pour le codage approprié que vous utilisez:http://en.cppreference.com/w/cpp/header/codecvt
la source
std::wstring str = std::wstring_convert<std::codecvt_utf<wchar_t>>().from_bytes("some string");
Solution de: http://forums.devshed.com/c-programming-42/wstring-to-string-444006.html
Attention , aucune conversion de jeu de caractères n'est en cours ici. Ce que cela fait est simplement d'affecter chaque itération
wchar_t
à unechar
- une conversion tronquée. Il utilise la chaîne std :: string :Comme indiqué dans les commentaires:
-
Et notez que les points de code dans la gamme
0x80 - 0x9F
de Win1252 ne pas fonctionner. Cela comprend€
,œ
,ž
,Ÿ
, ...la source
Au lieu d'inclure les paramètres régionaux et toutes ces choses fantaisistes, si vous savez pour FACT que votre chaîne est convertible, faites simplement ceci:
Exemple en direct ici
la source
Je crois que la manière officielle est toujours de parcourir les
codecvt
facettes (vous avez besoin d'une traduction adaptée aux paramètres régionaux), comme dansou quelque chose comme ça, je n'ai pas de code de travail qui traîne. Mais je ne sais pas combien de personnes utilisent ces machines de nos jours et combien demandent simplement des pointeurs à la mémoire et laissent ICU ou une autre bibliothèque gérer les détails sanglants.
la source
Il y a deux problèmes avec le code:
La conversion en
const std::string s( ws.begin(), ws.end() );
n'est pas requise pour mapper correctement les caractères larges à leur homologue étroit. Très probablement, chaque caractère large sera simplement transtypé enchar
.La résolution de ce problème est déjà donnée dans la réponse de kem et implique la
narrow
fonction de lactype
facette des paramètres régionaux .Vous écrivez la sortie à la fois
std::cout
etstd::wcout
dans le même programme. Les deuxcout
etwcout
sont associés au même flux (stdout
) et les résultats de l'utilisation du même flux à la fois comme flux orienté octet (comme lecout
fait) et comme flux orienté large (comme lewcout
fait) ne sont pas définis.La meilleure option est d'éviter de mélanger une sortie étroite et large au même flux (sous-jacent). Pour
stdout
/cout
/wcout
, vous pouvez essayer de changer l'orientation destdout
lorsque vous passez d'une sortie large à une sortie étroite (ou vice versa):la source
Ce code a deux formes pour convertir std :: string en std :: wstring et std :: wstring en std :: string. Si vous annulez # si WIN32 défini, vous obtenez le même résultat.
1. std :: string à std :: wstring
• MultiByteToWideChar WinAPI
• _mbstowcs_s_l
2. std :: wstring à std :: string
• WideCharToMultiByte WinAPI
• _wcstombs_s_l
3. Sous Windows, vous devez imprimer unicode à l'aide de WinAPI.
• WriteConsole
4. Sur le programme principal.
5. Enfin, vous avez besoin d'un support puissant et complet pour les caractères unicode dans la console. Je recommande ConEmu et définit comme terminal par défaut sous Windows . Vous devez connecter Visual Studio à ConEmu. N'oubliez pas que le fichier exe de Visual Studio est devenv.exe
Résultat
la source
Vous pourriez aussi bien utiliser directement la méthode étroite de la facette ctype:
la source
Au moment d'écrire cette réponse, la première recherche google pour "convertir la chaîne wstring" vous atterrirait sur cette page. Ma réponse montre comment convertir une chaîne en wstring, bien que ce ne soit PAS la vraie question, et je devrais probablement supprimer cette réponse mais qui est considérée comme mauvaise. Vous voudrez peut-être passer à cette réponse StackOverflow , qui est maintenant mieux classée que cette page.
Voici un moyen de combiner des constantes chaîne, wstring et chaîne mixte à wstring. Utilisez la classe wstringstream.
la source
En plus de simplement convertir les types, vous devez également être conscient du format réel de la chaîne.
Lors de la compilation pour le jeu de caractères multi-octets, Visual Studio et l'API Win supposent UTF8 (en fait, l'encodage Windows qui est Windows-28591 ).
Lors de la compilation pour le jeu de caractères Unicode Visual studio et l'API Win suppose UTF16.
Ainsi, vous devez également convertir la chaîne UTF16 au format UTF8, et pas seulement la convertir en std :: string.
Cela deviendra nécessaire lorsque vous travaillez avec des formats multi-caractères comme certaines langues non latines.
L'idée est de décider que représente
std::wstring
toujours UTF16 .Et représente
std::string
toujours UTF8 .Ce n'est pas appliqué par le compilateur, c'est plutôt une bonne politique à avoir. Notez les préfixes de chaîne que j'utilise pour définir UTF16 ( L ) et UTF8 ( u8 ).
Pour convertir entre les 2 types, vous devez utiliser: std :: codecvt_utf8_utf16 <wchar_t>
la source
Dans mon cas, je dois utiliser le caractère multi-octets (MBCS) et je veux utiliser std :: string et std :: wstring. Et ne peut pas utiliser c ++ 11. J'utilise donc mbstowcs et wcstombs.
Je fais la même fonction en utilisant new, delete [], mais c'est plus lent que ça.
Cela peut aider Comment: convertir entre différents types de chaînes
ÉDITER
Cependant, en cas de conversion en wstring et la chaîne source n'est pas un alphabet et une chaîne multi-octets, cela ne fonctionne pas. Je change donc wcstombs en WideCharToMultiByte.
EDIT pour utiliser «MultiByteToWideChar» au lieu de «wcstombs»
la source
wcstombs()
.Cette solution est inspirée de la solution de dk123 , mais utilise une facette codecvt dépendante des paramètres régionaux. Le résultat est dans une chaîne codée locale au lieu de UTF-8 (si elle n'est pas définie comme locale):
Je le cherchais, mais je ne le trouve pas. Enfin, j'ai trouvé que je peux obtenir la bonne facette en
std::locale
utilisant lastd::use_facet()
fonction avec le bon nom de type. J'espère que cela t'aides.la source
Au cas où quelqu'un d'autre serait intéressé: j'avais besoin d'une classe qui pourrait être utilisée de manière interchangeable où que ce soit
string
ouwstring
était prévu. La classe suivanteconvertible_string
, basée sur la solution de dk123 , peut être initialisé soit avec unstring
,char const*
,wstring
ouwchar_t const*
et peut être affecté par ou converti implicitement soit à unstring
ouwstring
(peut donc être passé dans une des fonctions qui prennent soit).la source
std::wstring
dans la classe, plutôt que de stockerstd::string
et de faire une conversion enstd::wstring
cas de besoin pour obtenir unstd::wstring
. Parce questd::wstring
c'est un peu plus rapidestd::string
et mieux compatible. Même il consomme plus de mémoire questd::string
.la source
J'utilise ci-dessous pour convertir wstring en chaîne.
la source
<string>
) et une définition pourWideCharToMultiByte()
- est-ce un wrapper autourstd::wctomb()
?la source