Cara mengonversi std :: string ke LPCWSTR di C ++ (Unicode)


Jawaban:


134

Terima kasih untuk tautan ke artikel MSDN. Inilah yang saya cari.

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
(Menemukan pertanyaan ini menjelajah secara acak; sudah lama sejak saya melakukan C ++.) Jadi pustaka standar tidak memiliki std :: string -> std :: wstring conversion? Sepertinya aneh; apakah ada alasan bagus?
Domenic

5
Jika Anda menggunakan std :: vector <wchar_t> untuk membuat penyimpanan untuk buf, maka jika ada yang mengeluarkan pengecualian, buffer sementara Anda akan dibebaskan.
Jason Harrison

81
alasan # 233 mengapa c ++ mengganggu saya .. 10 baris kode untuk konversi string sederhana = /
b1nary.atr0phy

2
Atau katakan saja wstring ws (s.begin (), s.end ()) ...?
CJBrew

3
@CJBrew: Untuk setiap masalah pasti ada solusinya, yang bersih, elegan, dan salah. Anda didasarkan pada asumsi bahwa masukan Anda hanya berisi karakter ASCII ( bukan ANSI).
IInspectable

121

Solusinya sebenarnya jauh lebih mudah daripada saran lainnya:

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

Yang terbaik dari semuanya, itu platform independen. h2h :)


2
Maaf Benny, tetapi itu tidak berhasil untuk saya, solusi Toran sendiri tampaknya berfungsi dengan baik (but..blegh!).
Iain Collins

32
Ini hanya berfungsi jika semua karakter adalah byte tunggal, yaitu ASCII atau ISO-8859-1 . Semua multi-byte akan gagal total, termasuk UTF-8.
Mark Ransom

Saya yakin Anda dapat menyederhanakan baris pertama menjadi: std :: wstring stemp (s.begin (), s.end ()); Itu akan menghilangkan kemungkinan salinan dan terlihat lebih sederhana; Perhatikan bahwa kompilator bisa saja menghilangkan salinan tersebut, tetapi ini masih terlihat lebih sederhana.
Kit10

13
Tuhan, ada apa dengan semua suara positif? Jawaban ini terkadang berhasil , karena kebetulan saja. Ini sepenuhnya mengabaikan pengkodean karakter . Anda tidak bisa begitu saja memperluas karakter sempit, dan berharap karakter tersebut secara ajaib berubah menjadi karakter lebar yang mewakili titik kode yang sama. Ini adalah moral yang setara dengan a reinterpret_cast. Kode ini tidak berfungsi. Jangan gunakan. .
IInspectable

2
@nik: Di Windows, a charbiasanya dikodekan sebagai ANSI. Dengan pengkodean ANSI, nilai 128 sampai 255 diinterpretasikan menggunakan halaman kode yang sedang aktif. Memasukkan nilai-nilai itu ke dalam wchar_t(pengkodean UTF-16 pada Windows) tidak akan memberikan hasil yang diinginkan. Jika Anda ingin tepatnya, ini bekerja tepat di 50% kasus. Dengan mempertimbangkan pengkodean karakter DBCS, persentase itu semakin menurun.
IInspectable

9

Jika Anda berada di lingkungan ATL / MFC, Anda dapat menggunakan makro konversi ATL:

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

. . .

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

Anda kemudian dapat menggunakan unicodeStr sebagai LPCWSTR. Memori untuk string unicode dibuat di tumpukan dan dilepaskan kemudian destruktor untuk unicodeStr dijalankan.


-1

Alih-alih menggunakan std :: string, Anda bisa menggunakan std :: wstring.

EDIT: Maaf ini tidak lebih jelas, tapi saya harus lari.

Gunakan std :: wstring :: c_str ()


9
T: "Saya perlu mengubah dari X ke Y." - A: "Carilah pekerjaan, di mana mereka menggunakan A, bukan X." Ini tidak berguna.
IInspectable

Tidak bisa melihat hutan untuk semua pepohonan? Ini berguna, karena persis seperti yang saya cari
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
Solusi ini telah diusulkan 9 tahun yang lalu oleh salah satu jawaban teratas
Nino Filiu

1
Dan itu salah 9 tahun yang lalu sebanyak itu salah hari ini. Komentar menjelaskan, mengapa ini hanya berfungsi untuk rentang unit kode yang sempit.
IInspectable
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.