Risposte:
str.c_str()
ti dà un const char *
, che è un LPCSTR
(Long Pointer to Constant STRing) - significa che è un puntatore a una 0
stringa di caratteri terminata. W
significa stringa larga (composta da wchar_t
invece di char
).
Chiama c_str()
per ottenere un const char *
( LPCSTR
) da un file std::string
.
È tutto nel nome:
LPSTR
- (lungo) puntatore alla stringa - char *
LPCSTR
- (lungo) puntatore a una stringa costante - const char *
LPWSTR
- Puntatore (lungo) alla stringa Unicode (ampia) - wchar_t *
LPCWSTR
- Puntatore (lungo) alla stringa Unicode (ampia) costante - const wchar_t *
LPTSTR
- Puntatore (lungo) a TCHAR (Unicode se UNICODE è definito, ANSI in caso contrario) stringa - TCHAR *
LPCTSTR
- Puntatore (lungo) alla stringa TCHAR costante - const TCHAR *
Puoi ignorare la parte L (lunga) dei nomi: è un residuo di Windows a 16 bit.
Questi sono i typedef definiti da Microsoft che corrispondono a:
LPCSTR: puntatore alla stringa const terminata da null di char
LPSTR: puntatore a una stringa di caratteri terminata da null char
(spesso viene passato un buffer e utilizzato come parametro di 'output')
LPCWSTR: puntatore a una stringa di const con terminazione nulla wchar_t
LPWSTR: puntatore a una stringa terminata da null wchar_t
(spesso viene passato un buffer e utilizzato come parametro di 'output')
Per "convertire" a std::string
in un LPCSTR dipende dal contesto esatto, ma di solito .c_str()
è sufficiente chiamare .
Funziona.
void TakesString(LPCSTR param);
void f(const std::string& param)
{
TakesString(param.c_str());
}
Nota che non dovresti tentare di fare qualcosa di simile.
LPCSTR GetString()
{
std::string tmp("temporary");
return tmp.c_str();
}
Il buffer restituito da .c_str()
è di proprietà std::string
dell'istanza e sarà valido solo fino a quando la stringa non verrà modificata o distrutta.
Convertire a std::string
in a LPWSTR
è più complicato. Volendo un LPWSTR
implica che è necessario un buffer modificabili ed è inoltre necessario essere sicuri che si capisce che cosa carattere codifica la std::string
sta utilizzando. Se std::string
contiene una stringa che utilizza la codifica predefinita del sistema (supponendo Windows, qui), è possibile trovare la lunghezza del buffer di caratteri wide richiesto ed eseguire la transcodifica utilizzando MultiByteToWideChar
(una funzione API Win32).
per esempio
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;
}
Usando LPWSTR
puoi cambiare il contenuto della stringa dove punta. Utilizzando LPCWSTR
non è stato 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 non essere temporaneo LPWSTR
dovresti fare una copia della stringa originale nell'heap. Controlla l'esempio di seguito:
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
}
La MultiByteToWideChar
risposta che ha dato Charles Bailey è quella corretta. Poiché LPCWSTR
è solo un typedef per const WCHAR*
, widestr
nel codice di esempio può essere utilizzato ovunque LPWSTR
sia previsto a o dove LPCWSTR
sia previsto a.
Una piccola modifica sarebbe quella di utilizzare al std::vector<WCHAR>
posto 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 devi iniziare a lavorare con stringhe larghe, puoi usare al std::wstring
posto di std::string
. Se vuoi lavorare con il TCHAR
tipo Windows , puoi usare std::basic_string<TCHAR>
. Convertire da std::wstring
a LPCWSTR
o da std::basic_string<TCHAR>
a LPCTSTR
è solo una questione di chiamata c_str
. È quando stai cambiando tra i caratteri ANSI e UTF-16 che MultiByteToWideChar
(e il suo inverso WideCharToMultiByte
) entra in scena.
La conversione è semplice:
std::string myString;
LPCSTR lpMyString = myString.c_str();
Una cosa a cui prestare attenzione qui è che c_str non restituisce una copia di myString, ma solo un puntatore alla stringa di caratteri che std :: string avvolge. Se vuoi / hai bisogno di una copia, dovrai crearne una tu stesso usando strcpy.
Il modo più semplice per convertire a std::string
in a LPWSTR
è secondo me:
std::string
in un filestd::vector<wchar_t>
wchar_t
nel vettore.std::vector<wchar_t>
ha un ctor basato su modelli che richiederà due iteratori, come gli iteratori std::string.begin()
e .end()
. wchar_t
Tuttavia, questo convertirà ogni carattere in a . Questo è valido solo se 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 di qualsiasi altra codifica, è più complicato. Dovrai quindi convertire i caratteri.
std::wstring
?