16

Làm cách nào để chuyển đổi nội dung của Nền tảng :: Chuỗi được sử dụng bởi các hàm mong đợi chuỗi char * dựa? Tôi giả định rằng WinRT cung cấp các hàm trợ giúp cho việc này nhưng tôi không thể tìm thấy chúng.Làm thế nào để chuyển đổi Platform :: String thành char *?

Cảm ơn!

+0

Bạn không thể yêu cầu chuyển đổi từ UTF-16LE, trừ khi bạn chỉ định mã hóa ký tự đích. Nó là gì? – IInspectable

Trả lời

13

Platform::String::Data() sẽ trả lại wchar_t const* trỏ đến nội dung của chuỗi (tương tự như std::wstring::c_str()). Platform::String đại diện cho một chuỗi bất biến, do đó không có người truy cập để nhận được wchar_t*. Bạn sẽ cần phải sao chép nội dung của nó, ví dụ: vào một số std::wstring để thực hiện thay đổi.

Không có trực tiếp cách để nhận char* hoặc char const*Platform::String sử dụng ký tự rộng (tất cả ứng dụng kiểu Metro là ứng dụng Unicode). Bạn có thể chuyển đổi sang multibyte bằng cách sử dụng WideCharToMultiByte.

+0

Có phương pháp "gián tiếp" cụ thể cho Metro chuyển đổi thành char * không? – djcouchycouch

+0

'WideCharToMultiByte' có thể gọi từ ứng dụng kiểu Metro. –

+0

Tôi hiểu. Được rồi cảm ơn! – djcouchycouch

1

Có phương pháp String::Data trả lại const char16*, là chuỗi unicode thô.

Chuyển đổi từ unicode thành ascii hoặc bất kỳ thứ gì, tức là char16* thành char*, là một vấn đề khác. Bạn có thể không cần nó vì hầu hết các phương pháp có phiên bản wchar của họ những ngày này.

+2

Than ôi, vì tôi không sống trong thế giới wchar. Hầu hết các mã tôi đang làm việc với là mã di sản dự kiến ​​chuỗi ký tự 8 bit. :) – djcouchycouch

13

Đây là một cách rất đơn giản để thực hiện việc này trong mã mà không phải lo lắng về độ dài bộ đệm. Chỉ sử dụng giải pháp này nếu bạn chắc chắn bạn đang đối phó với ASCII:

Platform::String^ fooRT = "aoeu"; 
std::wstring fooW(fooRT->Begin()); 
std::string fooA(fooW.begin(), fooW.end()); 
const char* charStr = fooA.c_str(); 

Hãy ghi nhớ rằng trong ví dụ này, char* là trên stack và sẽ biến mất khi nó rời khỏi phạm vi

+2

Đối với mọi vấn đề, có một giải pháp đơn giản, thanh lịch. Và sai. Giống như cái này. Bất kỳ ký tự nào bên ngoài phạm vi của các ký tự ASCII sẽ chỉ được đưa vào một biểu diễn ngẫu nhiên, tùy thuộc vào trạng thái hiện tại của luồng thực hiện. ** Không sử dụng giải pháp này. ** (Thật dễ dàng, vì nó thậm chí không biên dịch.) – IInspectable

+0

Sửa lỗi trình biên dịch. PS: Vẫn là một cách tốt đẹp để chuyển đổi nếu 100% chắc chắn rằng bạn chỉ phải đối phó với các ký tự ASCII – bas

1

Một giải pháp sử dụng wcstombs:

Platform::String^ platform_string = p_e->Uri->AbsoluteUri; 
const wchar_t* wide_chars = platform_string->Data(); 
char chars[512]; 
wcstombs(chars, wide_chars, 512); 
5

bạn không nên bỏ nhân vật rộng đến một char, bạn sẽ mangle ngôn ngữ sử dụng nhiều hơn một byte cho mỗi ký tự, ví dụ: Trung Quốc. Đây là phương pháp đúng.

#include <cvt/wstring> 
#include <codecvt> 

Platform::String^ fooRT = "foo"; 
stdext::cvt::wstring_convert<std::codecvt_utf8<wchar_t>> convert; 
std::string stringUtf8 = convert.to_bytes(fooRT->Data()); 
const char* rawCstring = stringUtf8.c_str(); 
+0

Hoặc một tuyến tính mà không sử dụng stdext 'char * raw = std :: wstring_convert >(). To_bytes (fooRT -> Data()) c_str(); ' – Quest

+2

Nhưng sử dụng phương thức @ Quest, biến' raw' sẽ trỏ tới bộ nhớ deallocated (đối tượng tạm thời biến mất sau khi biểu thức được đánh giá) nếu được sử dụng theo nghĩa đen. Sử dụng tốt hơn 'std :: string utf8 = std :: wstring_convert >(). To_bytes (fooRT-> Data())' trừ khi bạn chắc chắn mình đang làm gì. –

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