2011-07-28 16 views
26

Sto provando a convertire un programma per caratteri multibyte in Unicode.Converti char * in LPWSTR

Ho eseguito il programma e ho preceduto la stringa letterale con L in modo che assomiglino a L"string".

Questo ha funzionato, ma ora sto lasciato con una stringa stile C che non saranno conformi. Ho provato il L e la messa in TEXT() ma il L viene aggiunto al nome della variabile - non la stringa - se uso TEXT().

Ho provato a farlo a TCHAR ma poi si lamenta che non è possibile convertire un TCHAR in un char *.

Quali opzioni sono rimasto con?

Prima di downvotare come un matto so che C e C++ sono diversi. È una vecchia libreria C interna che è stata utilizzata in progetti C++ per diversi anni.

+1

Il motivo principale per cui qualcuno avrebbe downvote sarebbe più essere, secondo me, la mancanza di codice sorgente nella sua interrogazione. Un'immagine vale più di mille parole, e così fa un pezzo di codice. Anche un banale. – ereOn

+0

È possibile scrivere codice che funziona con 'TCHAR', indipendentemente dall'impostazione del compilatore, è sufficiente creare l'infrastruttura corretta. In C++, sovraccaricare fa tutto il lavoro pesante per te. –

+0

Questo C o C++ è correlato? –

risposta

30

La funzione std::mbstowcs è quello che state cercando:

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

-> ED: Il prefisso "L" funziona solo su letterali stringa, non variabili. < -

+1

che è deprecato, dovresti usare 'mbstowcs_s () ' – Olipro

+1

@Olipro: Questo è" deprecato "solo nel mondo Windows. L'OP non ha indicato quale piattaforma aveva come target. – ereOn

+3

è abbastanza implicito che la piattaforma sia Windows, ma se pensi diversamente, vai avanti e dimostrami che ho torto. – Olipro

11

Il modo più pulito per usare mbstowcs è chiamare due volte per trovare la lunghezza del risultato:

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; 

Non dimenticare di chiamare setlocale(LC_CTYPE, ""); all'inizio del vostro programma!

Il vantaggio rispetto a Windows MultiByteToWideChar è che questo è interamente C standard, anche se su Windows si potrebbe comunque preferire la funzione API di Windows.

Io di solito avvolgere questo metodo, insieme a quella opposta, in due funzioni di conversione string ->wstring e wstring ->string. Se si aggiungono sovraccarichi banali string ->string e wstring ->wstring, è possibile scrivere facilmente il codice che viene compilato con typedef Winapi TCHAR in qualsiasi impostazione.

[Modifica:] Ho aggiunto l'inizializzazione zero a buf, nel caso in cui si preveda di utilizzare direttamente l'array C. In genere restituirei il risultato come std::wstring(buf, wn), ma attenzione se si prevede di utilizzare array con terminazione null stile C. [/]

In un ambiente con multithreading è necessario passare uno stato di conversione thread-local alla funzione come il suo parametro finale (attualmente invisibile).

Ecco un mio small rant su questo argomento.

+1

+1 per mostrare come chiamare la funzione due volte per ottenere la lunghezza del buffer di output –

+0

Cheers. Nella privacy dei miei pensieri, in realtà uso un array di lunghezza variabile per 'buf', ma volevo evitare di farlo alla luce di SO scrutiny :-) –

+0

Update: al giorno d'oggi cercherei [' codecvt'] (http://en.cppreference.com/w/cpp/locale/codecvt), che include 'mbsrtowcs' /' wcsrtombs'. –

4

Questa versione, utilizzando la funzione API di Windows MultiByteToWideChar(), gestisce l'allocazione della memoria per stringhe di input arbitrariamente lunghe.

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

Perdita di memoria, perdita di memoria :-) –

+0

@Kerrek Nell'interesse della brevità ho omesso il codice che chiama 'free' ;-) –

+1

Preferisco che lo lasci così com'è che chiama' free() '! Questo è sicuramente un caso per la celebrata espressione 'delete []' :-) –

1

È possibile utilizzare CString, CStringA, CStringW di fare conversioni automatiche e convertire tra questi tipi. Inoltre, si può anche usare CStrBuf, CStrBufA, CStrBufW per ottenere modello RAII stringhe modificabili

+0

Nota, tuttavia, che sono specifici per ATL/MFC. – JBES

+0

@JBES, Sì, lo sono. Ho risposto 6+ anni fa, dove ATL/MFC è stato ampiamente utilizzato. Ora, anche il linguaggio C++ ha funzionalità di libreria per le conversioni. – Ajay