16

Come si converte il contenuto di Platform :: String per essere utilizzato da funzioni che prevedono una stringa basata su char? Suppongo che WinRT fornisca funzioni di aiuto per questo, ma non riesco a trovarli.Come convertire Platform :: String in char *?

Grazie!

+0

Non è possibile chiedere una conversione da UTF-16LE, a meno che non si specifichi la codifica dei caratteri di destinazione. Che cos'è? – IInspectable

risposta

13

Platform::String::Data() restituirà un valore wchar_t const* indicando il contenuto della stringa (simile a std::wstring::c_str()). Platform::String rappresenta una stringa immutabile, quindi non esiste un accessorio per ottenere un wchar_t*. Dovrai copiare il suo contenuto, ad es. in un std::wstring, per apportare modifiche.

Non c'è diretta modo per ottenere un char* o un char const* perché Platform::String utilizza caratteri estesi (tutte le applicazioni in stile Metro sono applicazioni Unicode). È possibile convertire in multibyte usando WideCharToMultiByte.

+0

Esistono metodi "indiretti" specifici per Metro per la conversione in char *? – djcouchycouch

+0

'WideCharToMultiByte' è richiamabile da un'app Metro style. –

+0

Capisco. Ok grazie! – djcouchycouch

1

C'è il metodo String::Data che restituisce const char16*, che è la stringa unicode non elaborata.

La conversione da unicode ad ASCII o qualsiasi altra cosa, ad esempio char16* a char*, è diversa. Probabilmente non ne hai bisogno dato che la maggior parte dei metodi hanno le loro versioni wchar in questi giorni.

+2

Ahimè, perché io non vivo in un mondo wchar. La maggior parte del codice con cui sto lavorando è un codice legacy che prevede le stringhe char a 8 bit. :) – djcouchycouch

13

Ecco un modo molto semplice per eseguire questa operazione nel codice senza preoccuparsi delle lunghezze del buffer. Utilizzare solo questa soluzione se si è certi che si tratta di ASCII:

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

Tenete presente che in questo esempio, il char* è in pila e andrà via una volta che lascia spazio

+2

Per ogni problema, c'è una soluzione, è semplice, elegante. E sbagliato Come questo. Qualsiasi carattere al di fuori dell'intervallo di caratteri ASCII verrà semplicemente macellato in una rappresentazione casuale, a seconda dello stato corrente dei thread in esecuzione. ** Non utilizzare questa soluzione. ** (Che è facile, perché non viene nemmeno compilato.) – IInspectable

+0

Risolto l'errore del compilatore. PS: ancora un bel modo di convertire se sei sicuro al 100% che devi trattare solo con caratteri ASCII – bas

1

A soluzione con 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

non si dovrebbe lanciare una vasta carattere a un char, si storpiare lingue che utilizzano più di un byte per carattere, ad esempio, Cinese. Ecco il metodo corretto.

#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

o uno lineare senza usare stdext 'char * raw = std :: wstring_convert (). To_bytes (fooRT -> Data()). C_str(); ' – Quest

+2

Ma usando il metodo di @ Quest, la variabile' raw' punterà alla memoria deallocated (l'oggetto temporaneo è scomparso dopo la valutazione dell'espressione) se usato letteralmente. Meglio usare 'std :: string utf8 = std :: wstring_convert >(). To_bytes (fooRT-> Data())' a meno che tu non sia sicuro di cosa stai facendo. –