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


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();

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 :)


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.


-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 ()


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();

-3

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


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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.