2011-07-28 95 views
26

Tôi đang cố gắng chuyển đổi một chương trình cho ký tự nhiều byte thành Unicode.Chuyển đổi char * sang LPWSTR

Tôi đã trải qua chương trình và đi trước các chuỗi ký tự bằng L để chúng trông giống như L"string".

Điều này đã hiệu quả nhưng bây giờ tôi còn lại với chuỗi kiểu C không phù hợp. Tôi đã thử các L và đặt nó trong TEXT() nhưng L được thêm vào tên biến - không phải là chuỗi - nếu tôi sử dụng TEXT().

Tôi đã cố gắng làm cho nó một TCHAR nhưng sau đó nó phàn nàn rằng nó không thể chuyển đổi một TCHAR đến một char *.

Tôi còn tùy chọn nào?

Trước khi bạn downvote như điên tôi biết C và C + + là khác nhau. Nó là một thư viện C trong nhà cũ đã được sử dụng trong các dự án C++ trong nhiều năm nay.

+1

Lý do chính khiến một người nào đó sẽ downvote nhiều hơn, imho, thiếu mã nguồn trong câu hỏi của bạn. Một hình ảnh trị giá một ngàn chữ, và một đoạn mã cũng vậy. Ngay cả một tầm thường. – ereOn

+0

Bạn chắc chắn có thể viết mã hoạt động với 'TCHAR' bất kể cài đặt trình biên dịch là gì, bạn chỉ cần tạo cơ sở hạ tầng phù hợp. Trong C++, quá tải thực hiện tất cả việc nâng hạng nặng cho bạn. –

+0

Đây có phải là C hoặc C++ liên quan không? –

Trả lời

30

Các std::mbstowcs chức năng là những gì bạn đang tìm kiếm:

char text[] = "something"; 
wchar_t wtext[20]; 
mbstowcs(wtext, text, strlen(text)+1);//Plus null 
LPWSTR ptr = wtext; 

-> ED: Các "L" tiền tố chỉ hoạt động trên xâu, không biến. < -

+1

không được chấp nhận, bạn nên sử dụng 'mbstowcs_s () ' – Olipro

+1

@Olipro: Điều này" không được chấp nhận "chỉ trong thế giới Windows. OP đã không tuyên bố nền tảng mà ông đã nhắm mục tiêu. – ereOn

+3

nó khá tiềm ẩn rằng nền tảng là Windows, nhưng nếu bạn nghĩ khác đi, hãy tiếp tục và chứng minh tôi sai. – Olipro

11

Cách sạch để sử dụng mbstowcs là để gọi nó hai lần để tìm ra chiều dài của kết quả:

const char * cs = <your input char*> 
    size_t wn = mbsrtowcs(NULL, &cs, 0, NULL); 

    // error if wn == size_t(-1) 

    wchar_t * buf = new wchar_t[wn + 1](); // value-initialize to 0 (see below) 

    wn = mbsrtowcs(buf, &cs, wn + 1, NULL); 

    // error if wn == size_t(-1) 

    assert(cs == NULL); // successful conversion 

    // result now in buf, return e.g. as std::wstring 

    delete[] buf; 

Đừng quên gọi setlocale(LC_CTYPE, ""); vào đầu chương trình của bạn!

Lợi thế so với Windows MultiByteToWideChar là đây hoàn toàn là tiêu chuẩn C, mặc dù trên Windows, bạn vẫn có thể sử dụng chức năng Windows API.

Tôi thường quấn phương thức này, cùng với phương thức đối diện, trong hai hàm chuyển đổi string ->wstringwstring ->string. Nếu bạn cũng thêm quá tải tầm thường string ->stringwstring ->wstring, bạn có thể dễ dàng viết mã biên dịch bằng kiểu gõ Winapi TCHAR trong bất kỳ cài đặt nào.

[Chỉnh sửa:] Tôi đã thêm zero-initialization vào buf, trong trường hợp bạn định sử dụng mảng C trực tiếp. Tôi thường sẽ trả về kết quả là std::wstring(buf, wn), tuy nhiên, nhưng hãy cẩn thận nếu bạn có kế hoạch sử dụng các mảng bị hủy kiểu null kiểu C. [/]

Trong môi trường đa luồng, bạn nên chuyển trạng thái chuyển đổi luồng cục bộ sang hàm là thông số cuối cùng (hiện đang ẩn).

Đây là số small rant của tôi về chủ đề này.

+1

+1 để hiển thị cách gọi hàm hai lần để lấy độ dài của bộ đệm đầu ra –

+0

Chúc mừng. Trong sự riêng tư của những suy nghĩ của riêng tôi, tôi thực sự sử dụng một mảng có độ dài biến đổi cho 'buf', nhưng tôi muốn tránh điều đó trong ánh sáng của SO giám sát :-) –

+0

Cập nhật: ngày nay tôi sẽ tìm [' codecvt'] (http://en.cppreference.com/w/cpp/locale/codecvt), bao gồm 'mbsrtowcs' /' wcsrtombs'. –

4

Phiên bản này, sử dụng chức năng API của Windows MultiByteToWideChar(), xử lý phân bổ bộ nhớ cho chuỗi đầu vào tùy ý dài.

int lenA = lstrlenA(input); 
int lenW = ::MultiByteToWideChar(CP_ACP, 0, input, lenA, NULL, 0); 
if (lenW>0) 
{ 
    output = new wchar_t[lenW]; 
    ::MultiByteToWideChar(CP_ACP, 0, input, lenA, output, lenW); 
} 
+3

Rò rỉ bộ nhớ, rò rỉ bộ nhớ :-) –

+0

@Kerrek Vì lợi ích của ngắn gọn, tôi bỏ qua mã gọi là 'free' ;-) –

+1

Tôi muốn bạn bỏ nó vì nó còn gọi là' free() '! Đây chắc chắn là một trường hợp cho biểu thức 'xóa []' nổi tiếng :-) –

1

Bạn có thể sử dụng CString, CStringA, CStringW để làm chuyển đổi tự động và chuyển đổi giữa các loại. Ngoài ra, bạn cũng có thể sử dụng CStrBuf, CStrBufA, CStrBufW để nhận các chuỗi có thể sửa đổi mẫu RAII

+0

Lưu ý, tuy nhiên, chúng là ATL/MFC cụ thể. – JBES

+0

@ JBES, Đúng vậy. Tôi trả lời nó 6+ năm trước, nơi ATL/MFC được sử dụng rộng rãi. Bây giờ, ngay cả ngôn ngữ C++ cũng có các tính năng thư viện cho các chuyển đổi. – Ajay

Các vấn đề liên quan