Comment convertir std :: string en LPCWSTR en C ++ (Unicode)

115

Je recherche une méthode ou un extrait de code pour convertir std :: string en LPCWSTR

Toran Billups
la source
1
Comment faire l'inverse?
Sohaib
Je suis venu de Google essayant de faire le contraire. Vous n'avez pas trouvé de méthode?
Tomáš Zato - Réintégrer Monica

Réponses:

134

Merci pour le lien vers l'article MSDN. Ceci est exactement ce que je cherchais.

std::wstring s2ws(const std::string& s)
{
    int len;
    int slength = (int)s.length() + 1;
    len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0); 
    wchar_t* buf = new wchar_t[len];
    MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
    std::wstring r(buf);
    delete[] buf;
    return r;
}

std::wstring stemp = s2ws(myString);
LPCWSTR result = stemp.c_str();
Toran Billups
la source
4
(J'ai trouvé cette question en parcourant au hasard; cela faisait longtemps que je n'avais pas fait de C ++.) Donc, la bibliothèque standard n'a pas de conversion std :: string -> std :: wstring? Cela semble bizarre; y a-t-il une bonne raison?
Domenic
5
Si vous utilisez std :: vector <wchar_t> pour créer un stockage pour buf, alors si quelque chose lève une exception, votre tampon temporaire sera libéré.
Jason Harrison
81
raison n ° 233 pour expliquer pourquoi c ++ me dérange pas ... 10 lignes de code pour une simple conversion de chaîne = /
b1nary.atr0phy
2
Ou dites simplement wstring ws (s.begin (), s.end ()) ...?
CJBrew
3
@CJBrew: Pour chaque problème, il existe une solution, qui est propre, élégante et fausse. Le vôtre est basé sur l'hypothèse que votre entrée contient uniquement des caractères ASCII (et non ANSI).
IInspectable le
121

La solution est en fait beaucoup plus simple que n'importe laquelle des autres suggestions:

std::wstring stemp = std::wstring(s.begin(), s.end());
LPCWSTR sw = stemp.c_str();

Mieux encore, il est indépendant de la plateforme. h2h :)

Benny Hilfiger
la source
2
Désolé Benny mais cela ne fonctionne pas pour moi, la propre solution de Toran semble bien fonctionner (mais..blegh!).
Iain Collins
32
Cela ne fonctionne que si tous les caractères sont à un octet, c'est-à-dire ASCII ou ISO-8859-1 . Tout ce qui est multi-octet échouera misérablement, y compris UTF-8.
Mark Ransom
Je crois que vous pouvez simplifier la première ligne en: std :: wstring stemp (s.begin (), s.end ()); Cela éliminerait une copie possible et paraîtrait plus simple; notez que le compilateur peut éliminer la copie de toute façon, mais cela reste un aspect plus simple.
Kit10
13
Seigneur, qu'y a-t-il avec toutes les votes favorables? Cette réponse fonctionne, parfois , par simple coïncidence. Il ignore complètement les encodages de caractères . Vous ne pouvez pas simplement élargir un caractère étroit et espérer qu'il se transforme comme par magie en un caractère large représentant le même point de code. C'est l'équivalent moral de a reinterpret_cast. Ce code ne fonctionne pas. Ne pas utiliser. .
IInspectable le
2
@nik: Sous Windows, a charest généralement codé en ANSI. Avec le codage ANSI, les valeurs 128 à 255 sont interprétées à l'aide de la page de codes actuellement active. Le fait de pousser ces valeurs dans un wchar_t(encodage UTF-16 sous Windows) ne produira pas le résultat souhaité. Si vous voulez être précis, cela fonctionne dans exactement 50% des cas. En tenant compte du codage des caractères DBCS, ce pourcentage diminue encore.
IInspectable
9

Si vous êtes dans un environnement ATL / MFC, vous pouvez utiliser la macro de conversion ATL:

#include <atlbase.h>
#include <atlconv.h>

. . .

string myStr("My string");
CA2W unicodeStr(myStr);

Vous pouvez ensuite utiliser unicodeStr comme LPCWSTR. La mémoire pour la chaîne unicode est créée sur la pile et libérée, puis le destructeur pour unicodeStr s'exécute.

17 sur 26
la source
-1

Au lieu d'utiliser une chaîne std :: string, vous pouvez utiliser une chaîne std :: wstring.

EDIT: Désolé, ce n'est pas plus explicatif, mais je dois courir.

Utilisez std :: wstring :: c_str ()

Ed S.
la source
9
Q: "J'ai besoin de convertir de X en Y." - A: "Cherchez un travail, où ils utilisent A au lieu de X." Cela ne sert à rien.
IInspectable le
Vous ne voyez pas la forêt pour tous les arbres? Ceci est utile, car c'est exactement ce que je cherchais
Charlie
-3
string  myMessage="helloworld";
int len;
int slength = (int)myMessage.length() + 1;
len = MultiByteToWideChar(CP_ACP, 0, myMessage.c_str(), slength, 0, 0); 
wchar_t* buf = new wchar_t[len];
MultiByteToWideChar(CP_ACP, 0, myMessage.c_str(), slength, buf, len);
std::wstring r(buf);
 std::wstring stemp = r.C_str();
LPCWSTR result = stemp.c_str();
Milind Morey
la source
-3

LPCWSTR lpcwName = std :: wstring (strname.begin (), strname.end ()). C_str ()

Milind Morey
la source
2
Cette solution a déjà été proposée il y a 9 ans par l'une des meilleures réponses
Nino Filiu
1
Et c'était faux il y a 9 ans autant que c'est faux aujourd'hui. Les commentaires expliquent pourquoi cela ne fonctionne que pour une gamme étroite d'unités de code.
IInspectable le