Làm thế nào để chuyển đổi std :: string sang LPCWSTR trong C ++ (Unicode)


115

Tôi đang tìm một phương pháp hoặc một đoạn mã để chuyển đổi std :: string thành LPCWSTR


1
Làm thế nào để chúng tôi làm điều ngược lại?
Sohaib

Tôi đến từ google cố gắng làm điều ngược lại. Bạn chưa tìm ra phương pháp?
Tomáš Zato - Phục hồi Monica

Câu trả lời:


134

Cảm ơn liên kết đến bài báo MSDN. Điều này thật đúng với gì mà tôi đã tìm kiếm.

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
(Tìm thấy câu hỏi này duyệt một cách ngẫu nhiên; đã lâu rồi tôi không làm C ++.) Vì vậy, thư viện tiêu chuẩn không có chuyển đổi std :: string -> std :: wstring? Điều đó có vẻ kỳ lạ; có một lý do chính đáng?
Domenic

5
Nếu bạn sử dụng std :: vector <wchar_t> để tạo bộ nhớ cho buf, thì nếu có bất kỳ điều gì ném ra ngoại lệ, bộ đệm tạm thời của bạn sẽ được giải phóng.
Jason Harrison

81
lý do # 233 tại sao c ++ lại làm phiền tôi..10 dòng mã cho một chuyển đổi chuỗi đơn giản = /
b1nary.atr0phy

2
Hay chỉ nói wstring ws (s.begin (), s.end ()) ...?
CJBrew

3
@CJBrew: Đối với mọi vấn đề đều có một giải pháp, đó là rõ ràng, thanh lịch và sai. Của bạn dựa trên giả định rằng đầu vào của bạn chỉ chứa các ký tự ASCII ( không phải ANSI).
Có thể mong đợi từ

121

Giải pháp thực sự dễ dàng hơn rất nhiều so với bất kỳ đề xuất nào khác:

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

Hơn hết, nó độc lập với nền tảng. h2h :)


2
Xin lỗi Benny nhưng điều đó không hiệu quả với tôi, mặc dù giải pháp của Toran dường như hoạt động tốt (nhưng..cao!).
Iain Collins

32
Điều này chỉ hoạt động nếu tất cả các ký tự là byte đơn, tức là ASCII hoặc ISO-8859-1 . Bất kỳ thứ gì nhiều byte sẽ thất bại thảm hại, kể cả UTF-8.
Đánh dấu giá chuộc

Tôi tin rằng bạn có thể đơn giản hóa dòng đầu tiên thành: std :: wstring stemp (s.begin (), s.end ()); Điều đó sẽ loại bỏ một bản sao có thể có và trông đơn giản hơn; lưu ý rằng trình biên dịch có thể loại bỏ bản sao, nhưng đây vẫn là một giao diện đơn giản hơn.
Kit10

13
Chúa ơi, những gì với tất cả các phiếu ủng hộ? Câu trả lời này đôi khi hoạt động bởi sự trùng hợp ngẫu nhiên. Nó hoàn toàn bỏ qua các bảng mã ký tự . Bạn không thể chỉ mở rộng một ký tự hẹp và hy vọng nó biến thành một ký tự rộng một cách kỳ diệu đại diện cho cùng một điểm mã. Nó là đạo đức tương đương với a reinterpret_cast. Mã này không hoạt động. Không được dùng. .
IInspectable

2
@nik: Trên Windows, a charthường được mã hóa là ANSI. Với mã hóa ANSI, các giá trị từ 128 đến 255 được diễn giải bằng cách sử dụng trang mã hiện đang hoạt động. Việc chuyển các giá trị đó vào một wchar_t(mã hóa UTF-16 trên Windows) sẽ không tạo ra kết quả mong muốn. Nếu bạn muốn chính xác, điều này hoạt động chính xác trong 50% trường hợp. Có tính đến mã hóa ký tự DBCS, tỷ lệ phần trăm đó giảm thêm.
IInspectable

9

Nếu bạn đang ở trong môi trường ATL / MFC, Bạn có thể sử dụng macro chuyển đổi ATL:

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

. . .

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

Sau đó, bạn có thể sử dụng unicodeStr làm LPCWSTR. Bộ nhớ cho chuỗi unicode được tạo trên ngăn xếp và được giải phóng sau đó hàm hủy cho unicodeStr thực thi.


-1

Thay vì sử dụng std :: string, bạn có thể sử dụng std :: wstring.

CHỈNH SỬA: Xin lỗi, điều này không giải thích được nhiều hơn, nhưng tôi phải chạy.

Sử dụng std :: wstring :: c_str ()


9
H: "Tôi cần chuyển đổi từ X sang Y." - A: "Hãy tìm một công việc, nơi họ đang sử dụng A thay vì X." Điều này là vô ích.
IInspectable

Không thể nhìn thấy rừng cho tất cả các cây? Điều này rất hữu ích, vì nó chính xác là những gì tôi đang tìm kiếm
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
Giải pháp này đã được đề xuất 9 năm trước bởi một trong những đầu câu trả lời
Nino Filiu

1
Và 9 năm trước nó sai nhiều như ngày nay. Các ý kiến ​​giải thích, tại sao điều này chỉ hoạt động cho một phạm vi hẹp các đơn vị mã.
IInspectable
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.