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

115

Saya mencari metode, atau potongan kode untuk mengubah std :: string ke LPCWSTR

Toran Billups
sumber
1
Bagaimana kita melakukan yang sebaliknya?
Sohaib
Saya berasal dari google mencoba melakukan yang sebaliknya. Apakah Anda tidak menemukan metode?
Tomáš Zato - Kembalikan Monica

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();
Toran Billups
sumber
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 :)

Benny Hilfiger
sumber
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.

17 dari 26
sumber
-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 ()

Ed S.
sumber
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();
Milind Morey
sumber
-3

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

Milind Morey
sumber
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