Std :: string'i C ++ (Unicode) ile LPCWSTR'ye dönüştürme


Yanıtlar:


134

MSDN makalesine bağlantı için teşekkürler. Bu tam olarak aradığım şeydi.

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
(Bu soruyu rastgele göz atarken buldum; C ++ 'ı yapmayalı uzun zaman oldu.) Yani standart kitaplıkta std :: string -> std :: wstring dönüşümü yok mu? Bu tuhaf görünüyor; iyi bir sebebi var mı
Domenic

5
Buf için depolama alanı oluşturmak için std :: vector <wchar_t> kullanırsanız, herhangi bir şey bir istisna atarsa, geçici tamponunuz serbest bırakılacaktır.
Jason Harrison

81
neden # 233, c ++ 'ın beni neden sinirlendirdiğine dair ... Basit bir dize dönüşümü için 10 satır kod = /
b1nary.atr0phy

2
Veya sadece wstring ws (s.begin (), s.end ()) diyelim ...?
CJBrew

3
@CJBrew: Her sorunun bir çözümü vardır, bu temiz, zarif ve yanlıştır. Sizinki, girişinizin yalnızca ASCII ( ANSI değil ) karakterleri içerdiği varsayımına dayanmaktadır .
2016

122

Çözüm aslında diğer önerilerden çok daha kolay:

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

Hepsinden iyisi, platformdan bağımsızdır. h2h :)


2
Üzgünüm Benny ama bu benim için işe yaramıyor, Toran'ın kendi çözümü yine de iyi çalışıyor gibi görünüyor (ama..bile!).
Iain Collins

32
Bu, yalnızca tüm karakterler tek bayt, yani ASCII veya ISO-8859-1 ise çalışır . UTF-8 dahil çok baytlı her şey berbat bir şekilde başarısız olur.
Mark Ransom

İlk satırı şu şekilde basitleştirebileceğinizi düşünüyorum: std :: wstring stemp (s.begin (), s.end ()); Bu, olası bir kopyayı ortadan kaldırır ve daha basit görünür; derleyicinin kopyayı yine de eleyebileceğini unutmayın , ancak bu yine de daha basit bir görünümdür.
Kit10

13
Tanrım, tüm olumlu oylar ne olacak? Bu cevap bazen sadece tesadüfen işe yarar. Karakter kodlamalarını tamamen yok sayar . Dar bir karakteri basitçe genişletemez ve sihirli bir şekilde aynı kod noktasını temsil eden geniş bir karaktere dönüşmesini umamazsınız. A'nın ahlaki eşdeğeridir reinterpret_cast. Bu kod çalışmıyor. Kullanmayın. .
2016

2
@nik: Windows'ta a chargenellikle ANSI olarak kodlanır. ANSI kodlamayla, 128 ile 255 arasındaki değerler o anda etkin olan kod sayfası kullanılarak yorumlanır. Bu değerlerin bir wchar_t(Windows'ta UTF-16 kodlaması) içine kaydırılması istenen sonucu vermeyecektir. Kesin olmak istiyorsanız, bu vakaların tam olarak% 50'sinde işe yarar. DBCS karakter kodlaması hesaba katıldığında, bu yüzde daha da azalır.
2018

9

ATL / MFC ortamındaysanız, ATL dönüştürme makrosunu kullanabilirsiniz:

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

. . .

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

Daha sonra unicodeStr'i bir LPCWSTR olarak kullanabilirsiniz. Unicode dizgisinin belleği yığın üzerinde yaratılır ve serbest bırakılır, ardından unicodeStr için yıkıcı çalıştırılır.


-1

Std :: string kullanmak yerine std :: wstring kullanabilirsiniz.

DÜZENLEME: Üzgünüm, bu daha açıklayıcı değil, ama koşmam gerekiyor.

Std :: wstring :: c_str () kullanın


9
S: "X'ten Y'ye dönüştürmem gerekiyor." - A: "X yerine A kullandıkları bir iş arayın." Bu işe yaramaz.
2016

Tüm ağaçlar için ormanı göremiyor musunuz? Bu yararlı, çünkü tam olarak aradığım şey buydu
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
Bu çözüm 9 yıl önce en iyi cevaplardan biri tarafından önerilmişti
Nino Filiu

1
Ve 9 yıl önce bugün olduğu kadar da yanlıştı. Yorumlar, bunun neden yalnızca dar bir kod birimi aralığı için çalıştığını açıklıyor.
IInspectable
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.