Cómo convertir std :: string a LPCWSTR en C ++ (Unicode)

115

Estoy buscando un método o un fragmento de código para convertir std :: string a LPCWSTR

Toran Billups
fuente
1
¿Cómo hacemos al revés?
Sohaib
Vengo de Google tratando de hacer lo contrario. ¿No encontraste un método?
Tomáš Zato - Reincorpora a Monica

Respuestas:

134

Gracias por el enlace al artículo de MSDN. Esto es exactamente lo que estaba buscando.

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
fuente
4
(Encontré esta pregunta navegando al azar; ha pasado mucho tiempo desde que hice C ++.) ¿Entonces la biblioteca estándar no tiene conversión std :: string -> std :: wstring? Eso parece extraño; hay una buena razon
Domenic
5
Si usa std :: vector <wchar_t> para crear almacenamiento para buf, entonces, si algo arroja una excepción, su búfer temporal se liberará.
Jason Harrison
81
Razón # 233 de por qué C ++ me molesta muchísimo ... 10 líneas de código para una conversión de cadena simple = /
b1nary.atr0phy
2
¿O simplemente diga wstring ws (al comienzo (), al final ()) ...?
CJBrew
3
@CJBrew: Para cada problema hay una solución, que es limpia, elegante e incorrecta. El suyo se basa en la suposición de que su entrada solo contiene caracteres ASCII ( no ANSI).
Inspectable
121

La solución es mucho más fácil que cualquiera de las otras sugerencias:

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

Lo mejor de todo es que es independiente de la plataforma. h2h :)

Benny Hilfiger
fuente
2
Lo siento Benny, pero eso no funciona para mí, la propia solución de Toran parece funcionar bien (pero ... ¡bum!).
Iain Collins
32
Esto solo funciona si todos los caracteres son de un solo byte, es decir, ASCII o ISO-8859-1 . Cualquier cosa de varios bytes fallará miserablemente, incluido UTF-8.
Mark Ransom
Creo que puede simplificar la primera línea a: std :: wstring stemp (s.begin (), s.end ()); Eso eliminaría una posible copia y parecería más simple; tenga en cuenta que el compilador podría eliminar la copia de todos modos, pero este es un aspecto más simple.
Kit10
13
Señor, ¿qué pasa con todos los votos a favor? Esta respuesta funciona, a veces , solo por coincidencia. Ignora por completo las codificaciones de caracteres . No se puede simplemente ampliar un carácter estrecho y esperar que se convierta mágicamente en un carácter ancho que represente el mismo punto de código. Es el equivalente moral de a reinterpret_cast. Este código no funciona. No utilice. .
Inspectable
2
@nik: En Windows, a chargeneralmente se codifica como ANSI. Con la codificación ANSI, los valores de 128 a 255 se interpretan utilizando la página de códigos actualmente activa. Introducir esos valores en un wchar_t(codificación UTF-16 en Windows) no producirá el resultado deseado. Si quiere ser preciso, esto funciona exactamente en el 50% de los casos. Teniendo en cuenta la codificación de caracteres DBCS, ese porcentaje disminuye aún más.
IInspectable
9

Si se encuentra en un entorno ATL / MFC, puede utilizar la macro de conversión ATL:

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

. . .

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

A continuación, puede utilizar unicodeStr como LPCWSTR. La memoria para la cadena Unicode se crea en la pila y se libera, luego se ejecuta el destructor para unicodeStr.

17 de 26
fuente
-1

En lugar de usar std :: string, podría usar std :: wstring.

EDITAR: Lo siento, esto no es más explicativo, pero tengo que correr.

Utilice std :: wstring :: c_str ()

Ed S.
fuente
9
P: "Necesito convertir de X a Y". - A: "Busque un trabajo, donde estén usando A en lugar de X". Esto es inútil.
Inspectable
¿No puedes ver el bosque por todos los árboles? Esto es útil, ya que es exactamente lo que estaba buscando
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
fuente
-3

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

Milind Morey
fuente
2
Esta solución ya fue propuesta hace 9 años por una de las principales respuestas
Nino Filiu
1
Y estuvo tan mal hace 9 años como hoy. Los comentarios explican por qué esto solo funciona para un rango limitado de unidades de código.
Inenspectable