Como converter std :: string em LPCWSTR em C ++ (Unicode)


Respostas:


133

Obrigado pelo link para o artigo do MSDN. Isso é exatamente o que eu estava procurando.

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
(Esta questão foi encontrada navegando aleatoriamente; já se passou muito tempo desde que fiz C ++.) Então a biblioteca padrão não tem conversão std :: string -> std :: wstring? Isso parece estranho; existe um bom motivo?
Domenic

5
Se você usar std :: vector <wchar_t> para criar armazenamento para buf, então se qualquer coisa lançar uma exceção, seu buffer temporário será liberado.
Jason Harrison

81
razão # 233 sobre por que c ++ me irrita ... 10 linhas de código para uma conversão de string simples = /
b1nary.atr0phy

2
Ou apenas diga wstring ws (s.begin (), s.end ()) ...?
CJBrew

3
@CJBrew: Para cada problema existe uma solução, que é limpa, elegante e errada. O seu é baseado na suposição de que sua entrada contém apenas caracteres ASCII ( não ANSI).
Inspecionável

121

A solução é muito mais fácil do que qualquer uma das outras sugestões:

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

O melhor de tudo é que é independente de plataforma. h2h :)


2
Desculpe Benny, mas isso não funciona para mim, a própria solução de Toran parece funcionar bem (mas..blegh!).
Iain Collins

32
Isso só funciona se todos os caracteres forem de byte único, ou seja, ASCII ou ISO-8859-1 . Qualquer coisa multibyte falhará terrivelmente, incluindo UTF-8.
Mark Ransom

Eu acredito que você pode simplificar a primeira linha para: std :: wstring stemp (s.begin (), s.end ()); Isso eliminaria uma possível cópia e pareceria mais simples; observe que o compilador pode eliminar a cópia de qualquer maneira, mas essa ainda é uma aparência mais simples.
Kit10

13
Senhor, o que há com todos os votos positivos? Essa resposta funciona, às vezes , apenas por coincidência. Ele ignora completamente as codificações de caracteres . Você não pode simplesmente ampliar um caractere estreito e esperar que ele magicamente se transforme em um caractere largo representando o mesmo ponto de código. É o equivalente moral de a reinterpret_cast. Este código não funciona. Não use. .
Inspecionável

2
@nik: No Windows, a chargeralmente é codificado como ANSI. Com a codificação ANSI, os valores 128 a 255 são interpretados usando a página de código ativa no momento. Empurrar esses valores para um wchar_t(codificação UTF-16 no Windows) não produzirá o resultado desejado. Se você quiser ser preciso, isso funciona em exatamente 50% dos casos. Levando em consideração a codificação de caracteres DBCS, essa porcentagem diminui ainda mais.
Inspecionável de

9

Se você estiver em um ambiente ATL / MFC, poderá usar a macro de conversão ATL:

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

. . .

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

Você pode então usar unicodeStr como um LPCWSTR. A memória para a string Unicode é criada na pilha e liberada e, em seguida, o destruidor para unicodeStr é executado.


0

Em vez de usar um std :: string, você pode usar um std :: wstring.

EDIT: Desculpe, isso não é mais explicativo, mas eu tenho que correr.

Use std :: wstring :: c_str ()


9
P: "Preciso converter de X em Y." - A: "Procure um emprego, onde eles estão usando A em vez de X." Isso é inútil.
Inspecionável

Não consegue ver a floresta com todas as árvores? Isso é útil, pois é exatamente o que eu estava procurando
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 solução já foi proposta há 9 anos por uma das principais respostas
Nino Filiu

1
E estava errado nove anos atrás tanto quanto está errado hoje. Os comentários explicam por que isso só funciona para uma faixa estreita de unidades de código.
Inspecionável
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.