วิธีการแปลง std :: string เป็น LPCWSTR ใน C ++ (Unicode)


115

ฉันกำลังมองหาวิธีการหรือข้อมูลโค้ดสำหรับแปลง std :: string เป็น LPCWSTR


1
เราจะทำย้อนกลับได้อย่างไร?
Sohaib

ฉันมาจาก Google พยายามทำสิ่งที่ตรงกันข้าม คุณไม่พบวิธีการ?
Tomáš Zato - คืนสถานะ Monica

คำตอบ:


134

ขอบคุณสำหรับลิงก์ไปยังบทความ MSDN นี่คือสิ่งที่ฉันกำลังมองหา

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
(พบคำถามนี้เรียกดูแบบสุ่มเป็นเวลานานแล้วที่ฉันทำ C ++) ดังนั้นไลบรารีมาตรฐานจึงไม่มีการแปลง std :: string -> std :: wstring? มันดูแปลก ๆ มีเหตุผลที่ดีหรือไม่?
Domenic

5
หากคุณใช้ std :: vector <wchar_t> เพื่อสร้างพื้นที่จัดเก็บสำหรับ buf หากมีสิ่งใดที่ทำให้เกิดข้อยกเว้นบัฟเฟอร์ชั่วคราวของคุณจะถูกปลดปล่อย
Jason Harrison

81
เหตุผลที่ # 233 ว่าทำไม c ++ สร้างความรำคาญให้กับฉัน .. 10 บรรทัดของโค้ดสำหรับการแปลงสตริงอย่างง่าย = /
b1nary.atr0phy

2
หรือเพียงแค่พูด wstring ws (s.begin (), s.end ()) ... ?
CJBrew

3
@CJBrew: สำหรับทุกปัญหามีทางแก้ไขที่สะอาดสวยงามและไม่ถูกต้อง ของคุณเป็นไปตามสมมติฐานที่ว่าข้อมูลของคุณมีอักขระ ASCII ( ไม่ใช่ ANSI) เท่านั้น
ระบุได้

122

วิธีแก้ปัญหานั้นง่ายกว่าคำแนะนำอื่น ๆ มาก:

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

เหนือสิ่งอื่นใดแพลตฟอร์มนี้เป็นอิสระ h2h :)


2
ขอโทษ Benny แต่นั่นไม่ได้ผลสำหรับฉันวิธีแก้ปัญหาของ Toran เองดูเหมือนจะใช้ได้ดี (แต่.. เบลจ์!)
Iain Collins

32
นี้จะทำงานเฉพาะถ้าตัวละครทั้งหมดที่มี byte เดียวคือ ASCII หรือISO-8859-1 สิ่งที่หลายไบต์จะล้มเหลวอย่างน่าสังเวชรวมถึง UTF-8
Mark Ransom

ฉันเชื่อว่าคุณสามารถลดความซับซ้อนของบรรทัดแรกเป็น: std :: wstring stemp (s.begin (), s.end ()); นั่นจะกำจัดสำเนาที่เป็นไปได้และดูง่ายขึ้น โปรดทราบว่าคอมไพลเลอร์อาจกำจัดสำเนาได้ แต่ก็ยังดูง่ายกว่า
Kit10

13
พระเจ้าอะไรกับการโหวตเพิ่มทั้งหมด? คำตอบนี้ใช้ได้ผลบางครั้งโดยบังเอิญเพียงอย่างเดียว มันสมบูรณ์ละเว้นอักขระการเข้ารหัส คุณไม่สามารถขยายอักขระแคบ ๆ เพียงอย่างเดียวและหวังว่าจะเปลี่ยนเป็นอักขระแบบกว้างที่แสดงจุดรหัสเดียวกันได้อย่างน่าอัศจรรย์ เป็นคุณธรรมเทียบเท่ากับreinterpret_cast. รหัสนี้ใช้ไม่ได้ ไม่ได้ใช้. .
IInspectable

2
@nik: ใน Windows a charมักจะเข้ารหัสเป็น ANSI ด้วยการเข้ารหัส ANSI ค่า 128 ถึง 255 จะถูกตีความโดยใช้โค้ดเพจที่ใช้งานอยู่ในปัจจุบัน การเปลี่ยนค่าเหล่านั้นเป็นwchar_t(การเข้ารหัส UTF-16 บน Windows) จะไม่ได้ผลลัพธ์ที่ต้องการ หากคุณต้องการความแม่นยำสิ่งนี้ใช้ได้กับ 50% ของกรณี เมื่อพิจารณาการเข้ารหัสอักขระ DBCS เปอร์เซ็นต์นั้นจะลดลงอีก
IInspectable

9

หากคุณอยู่ในสภาพแวดล้อม ATL / MFC คุณสามารถใช้มาโครการแปลง ATL:

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

. . .

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

จากนั้นคุณสามารถใช้ unicodeStr เป็น LPCWSTR หน่วยความจำสำหรับสตริงยูนิโคดถูกสร้างขึ้นบนสแต็กและปล่อยจากนั้นตัวทำลายสำหรับ unicodeStr จะดำเนินการ


-1

แทนที่จะใช้ std :: string คุณสามารถใช้ std :: wstring

แก้ไข: ขออภัยนี่ไม่ใช่คำอธิบายมากกว่านี้ แต่ฉันต้องเรียกใช้

ใช้ std :: wstring :: c_str ()


9
ถาม: "ฉันต้องแปลงจาก X เป็น Y" - A: "มองหางานโดยใช้ A แทน X" สิ่งนี้ไม่มีประโยชน์
IInspectable

ไม่สามารถมองเห็นป่าสำหรับต้นไม้ทั้งหมด? สิ่งนี้มีประโยชน์เพราะมันคือสิ่งที่ฉันกำลังมองหา
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
โซลูชันนี้ได้รับการเสนอแล้วเมื่อ 9 ปีก่อนโดยหนึ่งในคำตอบยอดนิยม
Nino Filiu

1
และมันผิดเมื่อ 9 ปีที่แล้วเท่าที่ผิดในปัจจุบัน ความคิดเห็นอธิบายว่าเหตุใดจึงใช้ได้กับหน่วยรหัสช่วงแคบ ๆ เท่านั้น
IInspectable
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.