2009-07-29 16 views
93

Come posso convertire un std::string in LPCSTR? Inoltre, come posso convertire un std::string in LPWSTR?Come convertire std :: string in LPCSTR?

io sono totalmente confuso con questi LPCSTRLPSTRLPWSTR e LPCWSTR.

Sono LPWSTR e LPCWSTR lo stesso?

risposta

91

str.c_str() ti dà una const char *, che è un (Long puntatore a stringa costante) LPCSTR - significa che si tratta di un puntatore ad una stringa terminata 0 di caratteri. W significa stringa larga (composta da wchar_t anziché da char).

+5

Punto di scarsa importanza: su x64 LPCSTR sarebbe un puntatore a 64 bit su una stringa (costante) con terminazione null. – Joel

2

La conversione è semplice:

std :: string str; LPCSTR lpcstr = str.c_str();

138

Chiama c_str() per ottenere un const char * (LPCSTR) da un std::string.

E 'tutto nel nome:

LPSTR - (lunga) puntatore a stringa - char *

LPCSTR - (lunga) puntatore alla stringa costante - const char *

LPWSTR - (lungo) puntatore Unicode (wide) string - wchar_t *

LPCWSTR - (long) puntatore a Unicode costante (largo) stringa - const wchar_t *

LPTSTR - (lunga) puntatore a TCHAR (Unicode se UNICODE è definito, ANSI se non) stringa - TCHAR *

LPCTSTR - (lunga) puntatore a stringa TCHAR costante - const TCHAR *

È può ignorare la parte L (lunga) dei nomi - è un holdover da Windows a 16 bit.

32

Questi sono Microsoft typedefs definiti corrispondenti:

LPCSTR: puntatore a zero finale const string di char

LPSTR: puntatore null stringa char terminato di char (spesso un buffer viene passato e utilizzato come un param 'uscita')

LPCWSTR: puntatore alla stringa Null terminata del const wchar_t

LPWSTR: puntatore su null t stringa erminated di wchar_t (spesso un buffer viene passato ed utilizzato come parametro 'uscita')

"convertire" un std::string ad un LPCSTR dipende dal contesto esatta ma solitamente chiamata .c_str() è sufficiente.

Questo funziona.

void TakesString(LPCSTR param); 

void f(const std::string& param) 
{ 
    TakesString(param.c_str()); 
} 

Si noti che non si dovrebbe tentare di fare qualcosa di simile.

LPCSTR GetString() 
{ 
    std::string tmp("temporary"); 
    return tmp.c_str(); 
} 

Il buffer restituito da .c_str() è di proprietà l'istanza std::string e saranno validi solo finché la corda sia modificata o distrutta.

Per convertire un std::string in un LPWSTR è più complicato. La richiesta di un LPWSTR implica che è necessario un buffer modificabile e devi anche essere sicuro di aver compreso quale codifica dei caratteri utilizza il codice std::string. Se std::string contiene una stringa che utilizza la codifica predefinita di sistema (presupponendo windows, qui), quindi è possibile trovare la lunghezza del buffer di caratteri wide richiesto ed eseguire la transcodifica utilizzando MultiByteToWideChar (una funzione API Win32).

ad es.

void f(const std:string& instr) 
{ 
    // Assumes std::string is encoded in the current Windows ANSI codepage 
    int bufferlen = ::MultiByteToWideChar(CP_ACP, 0, instr.c_str(), instr.size(), NULL, 0); 

    if (bufferlen == 0) 
    { 
     // Something went wrong. Perhaps, check GetLastError() and log. 
     return; 
    } 

    // Allocate new LPWSTR - must deallocate it later 
    LPWSTR widestr = new WCHAR[bufferlen + 1]; 

    ::MultiByteToWideChar(CP_ACP, 0, instr.c_str(), instr.size(), widestr, bufferlen); 

    // Ensure wide string is null terminated 
    widestr[bufferlen] = 0; 

    // Do something with widestr 

    delete[] widestr; 
} 
3

di conversione è semplice:

std::string myString; 

LPCSTR lpMyString = myString.c_str(); 

Una cosa da stare attenti è che c_str non restituisce una copia di myString, ma solo un puntatore alla stringa di caratteri che std :: avvolge stringa . Se vuoi/hai bisogno di una copia, devi crearne una tu stessa usando strcpy.

+0

Come convertire std :: String in LPWSTR ??? – Cute

1

Il modo più semplice per convertire un std::string ad un LPWSTR è a mio parere:

  1. Convertire il std::string ad un std::vector<wchar_t>
  2. prendere l'indirizzo del primo wchar_t nel vettore.

std::vector<wchar_t> ha un ctor template che avrà due iteratori, come le std::string.begin() e .end() iteratori. Questo convertirà ogni char in un wchar_t, però. Questo è valido solo se lo std::string contiene ASCII o Latin-1, a causa del modo in cui i valori Unicode assomigliano ai valori Latin-1.Se contiene CP1252 o caratteri da qualsiasi altra codifica, è più complicato. Dovrai quindi convertire i caratteri.

14

Utilizzando LPWSTR è possibile modificare il contenuto della stringa a cui punta. Utilizzando LPCWSTR non è possibile modificare il contenuto della stringa a cui punta.

std::string s = SOME_STRING; 
// get temporary LPSTR (not really safe) 
LPSTR pst = &s[0]; 
// get temporary LPCSTR (pretty safe) 
LPCSTR pcstr = s.c_str(); 
// convert to std::wstring 
std::wstring ws; 
ws.assign(s.begin(), s.end()); 
// get temporary LPWSTR (not really safe) 
LPWSTR pwst = &ws[0]; 
// get temporary LPCWSTR (pretty safe) 
LPCWSTR pcwstr = ws.c_str(); 

LPWSTR è solo un puntatore alla stringa originale. Non dovresti restituirlo dalla funzione usando l'esempio sopra. Per ottenere non temporaneamente LPWSTR, è necessario creare una copia della stringa originale nell'heap. Controlla il campione qui sotto:

LPWSTR ConvertToLPWSTR(const std::string& s) 
{ 
    LPWSTR ws = new wchar_t[s.size()+1]; // +1 for zero at the end 
    copy(s.begin(), s.end(), ws); 
    ws[s.size()] = 0; // zero at the end 
    return ws; 
} 

void f() 
{ 
    std::string s = SOME_STRING; 
    LPWSTR ws = ConvertToLPWSTR(s); 

    // some actions 

    delete[] ws; // caller responsible for deletion 
} 
4

La risposta MultiByteToWideChar che Charles Bailey ha dato è quella giusta. Perché LPCWSTR è solo un typedef per const WCHAR*, widestr nel codice di esempio che può essere utilizzato ovunque sia previsto un LPWSTR o dove è previsto un LPCWSTR.

Un ritocco minore sarebbe quella di utilizzare std::vector<WCHAR> invece di un array gestito manualmente:

// using vector, buffer is deallocated when function ends 
std::vector<WCHAR> widestr(bufferlen + 1); 

::MultiByteToWideChar(CP_ACP, 0, instr.c_str(), instr.size(), &widestr[0], bufferlen); 

// Ensure wide string is null terminated 
widestr[bufferlen] = 0; 

// no need to delete; handled by vector 

Inoltre, se avete bisogno di lavorare con ampi archi per cominciare, è possibile utilizzare al posto di std::wstringstd::string. Se si desidera lavorare con il tipo Windows TCHAR, è possibile utilizzare std::basic_string<TCHAR>. La conversione da std::wstring a LPCWSTR o da std::basic_string<TCHAR> a LPCTSTR è solo una questione di chiamata c_str. È quando cambi tra caratteri ANSI e UTF-16 che MultiByteToWideChar (e il suo inverso WideCharToMultiByte) entra nell'immagine.

Problemi correlati