2011-07-14 41 views
11

Tôi muốn chuyển đổi một số bình thường string thành wide string. Đối với điều này tôi đang sử dụng hàm MultiByteToWideChar. Nhưng tôi đã không thành công khi sử dụng chức năng này. Đây là những gì tôi đã làm cho đến bây giờ.vấn đề khi sử dụng MultiByteToWideChar

VÍ DỤ

string x = "This is c++ not java"; 
wstring Wstring; 
int c = MultiByteToWideChar(CP_UTF8 , 0 , x.c_str() , x.size() , &Wstring , 0); 
// The above line produces error which says 'MultiByteToWideChar' : cannot convert parameter 5 from 'std::wstring *' to 'LPWSTR' 

Làm thế nào tôi có thể khắc phục lỗi này? Và đối số thứ sáu của chức năng này là gì? Là 0 ok?

+1

Bạn không thể chuyển con trỏ tới 'std :: wstring' đến hàm này. –

Trả lời

26

Nếu tham số cuối cùng cho MultiByteToWideChar bằng 0, bạn nên chuyển NULL làm thông số trước đó. Theo số doc:

Nếu giá trị này bằng 0, hàm trả về kích thước bộ đệm yêu cầu, trong ký tự, bao gồm cả ký tự null kết thúc và không sử dụng bộ đệm lpWideCharStr.

Vì vậy, cuộc gọi đầu tiên tới MultiByteToWideChar sẽ trả về kích thước bộ đệm bạn cần cho chuỗi rộng. Sau đó, bạn sẽ có được một bộ đệm không phải là đủ lớn để chứa chuỗi rộng, và chuyển nó vào một cuộc gọi khác tới MultiByteToWideChar (lần này, đối số cuối cùng phải là kích thước thực của bộ đệm và không phải 0).

Một ví dụ scetchy:

int wchars_num = MultiByteToWideChar(CP_UTF8 , 0 , x.c_str() , -1, NULL , 0); 
wchar_t* wstr = new wchar_t[wchars_num]; 
MultiByteToWideChar(CP_UTF8 , 0 , x.c_str() , -1, wstr , wchars_num); 
// do whatever with wstr 
delete[] wstr; 

Ngoài ra, lưu ý việc sử dụng -1 như là đối số cbMultiByte - nó giúp bạn tiết kiệm từ đối phó với NULLs chấm dứt.

+1

+1 để nhấn mạnh nhu cầu gọi MultiByteToWideChar hai lần, điều này rất cần thiết cho các hàm chuyển đổi ký tự. – Stephan

+0

@ eran sự khác nhau giữa 'wchar_t *' và 'LPTSTR' là gì? –

+0

@Suhail Gupta, nếu bạn đang biên dịch với Unicode, thì nó hoàn toàn giống nhau. Trong quá trình xây dựng nhiều byte, LPTSTR sẽ mở rộng thành 'char *' thông thường. Sử dụng các macro này cho phép bạn tạo cả bản dựng Unicode và không phải Unicode. Tôi không thể nghĩ ra một lý do để làm điều đó những ngày này, mặc dù, và kể từ Unicode bây giờ là mặc định trong VS, sử dụng hoặc là một trong số họ. – eran

0

Hàm không thể đưa con trỏ đến chuỗi C++. Nó sẽ mong đợi một con trỏ đến một bộ đệm của các ký tự rộng có kích thước đầy đủ - bạn phải tự cấp phát bộ đệm này.

string x = "This is c++ not java"; 
wstring Wstring; 
Wstring.resize(x.size()); 
int c = MultiByteToWideChar(CP_UTF8 , 0 , x.c_str() , x.size() , &Wstring[0], 0); 
+0

bạn có thể vui lòng xây dựng những gì bạn đã làm không? –

+1

'MultiByteToWideChar' hy vọng một tham số của kiểu' wchar_t * '. Wstring có kiểu 'std :: wstring' - vì vậy nó không thể được chuyển tới' MultiByteToWideChar' (thậm chí không phải là con trỏ tới nó). Nhưng tin tốt là, 'std :: wstring' lưu trữ dữ liệu của nó dưới dạng' wchar_t * 'và cung cấp hai hàm để truy cập vào dữ liệu bên trong này:' data() '(được sử dụng ở đây) và' c_str() '. – Stephan

+1

@DeadMG, lưu ý rằng wstring.data() trả về một const wchar_t *, mà accoding để cplusplus.com không nên được sửa đổi trực tiếp (bạn có thể biết tốt hơn so với tôi những gì sẽ có hiệu lực làm như vậy). OTOH, đối số cuối cùng của MBTWC là 0, không có gì sẽ được đặt trong bộ đệm đó ... – eran

1

Câu hỏi thứ hai về điều này, sáng nay!

WideCharToMultiByte() và MultiByteToWideChar() là một cơn đau để sử dụng. Mỗi chuyển đổi yêu cầu hai cuộc gọi đến các thói quen và bạn phải chăm sóc phân bổ/giải phóng bộ nhớ và đảm bảo các chuỗi được chấm dứt chính xác. Bạn cần một wrapper!

Tôi có trình bao bọc C++ thuận tiện trên blog của mình, here, bạn được hoan nghênh sử dụng.

Đây là số khác question sáng nay

0

Bạn có thể thử giải pháp này bên dưới. Tôi đã thử nghiệm, nó hoạt động, phát hiện các ký tự đặc biệt (ví dụ: º ä ç á) và hoạt động trên Windows XP, Windows 2000 với SP4 trở lên, Windows 7, 8, 8.1 và 10. Sử dụng std::wstring thay vì new wchar_t/delete, chúng tôi giảm các vấn đề với tài nguyên bị rò rỉ, bộ đệm tràn và đống bị hỏng.

dwFlags được đặt thành MB_ERR_INVALID_CHARS để hoạt động trên Windows 2000 với SP4 trở lên, Windows XP. Nếu cờ này không được đặt, hàm sẽ tự động giảm các điểm mã bất hợp pháp.

std::wstring ConvertStringToWstring(const std::string &str) 
{ 
    if (str.empty()) 
    { 
     return std::wstring(); 
    } 
    int num_chars = MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, str.c_str(), str.length(), NULL, 0); 
    std::wstring wstrTo; 
    if (num_chars) 
    { 
     wstrTo.resize(num_chars); 
     if (MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, str.c_str(), str.length(), &wstrTo[0], num_chars)) 
     { 
      return wstrTo; 
     } 
    } 
    return std::wstring(); 
} 
Các vấn đề liên quan