Come convertire std :: string in LPCSTR?


111

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

Sono totalmente confuso con questi LPCSTR LPSTR LPWSTRe LPCWSTR.

Sono LPWSTRe LPCWSTRla stessa cosa?

Risposte:


114

str.c_str()ti dà un const char *, che è un LPCSTR(Long Pointer to Constant STRing) - significa che è un puntatore a una 0stringa di caratteri terminata. Wsignifica stringa larga (composta da wchar_tinvece di char).


5
Punto critico minore: su x64 LPCSTR sarebbe un puntatore a 64 bit a una stringa con terminazione null (costante).
Joel

154

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.


32

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::stringin 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::stringdell'istanza e sarà valido solo fino a quando la stringa non verrà modificata o distrutta.

Convertire a std::stringin a LPWSTRè più complicato. Volendo un LPWSTRimplica che è necessario un buffer modificabili ed è inoltre necessario essere sicuri che si capisce che cosa carattere codifica la std::stringsta utilizzando. Se std::stringcontiene 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;
}

18

Usando LPWSTRpuoi cambiare il contenuto della stringa dove punta. Utilizzando LPCWSTRnon è 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 LPWSTRdovresti 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
}

4

La MultiByteToWideCharrisposta che ha dato Charles Bailey è quella corretta. Poiché LPCWSTRè solo un typedef per const WCHAR*, widestrnel codice di esempio può essere utilizzato ovunque LPWSTRsia previsto a o dove LPCWSTRsia 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::wstringposto di std::string. Se vuoi lavorare con il TCHARtipo Windows , puoi usare std::basic_string<TCHAR>. Convertire da std::wstringa LPCWSTRo 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.


3

La conversione è semplice:

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


3

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.


1

Il modo più semplice per convertire a std::stringin a LPWSTRè secondo me:

  1. Converti il ​​file std::stringin un filestd::vector<wchar_t>
  2. Prendi l'indirizzo del primo wchar_tnel vettore.

std::vector<wchar_t>ha un ctor basato su modelli che richiederà due iteratori, come gli iteratori std::string.begin()e .end(). wchar_tTuttavia, questo convertirà ogni carattere in a . Questo è valido solo se std::stringcontiene 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.


Perché non usare std::wstring?
Timmmm

@Timmmm: C ++ 11 ha rafforzato le specifiche poiché le implementazioni non hanno sfruttato le vecchie regole, oggi sarebbe OK.
MSalters

1
std::string myString("SomeValue");
LPSTR lpSTR = const_cast<char*>(myString.c_str());

myString è la stringa di input e lpSTR è l' equivalente di LPSTR .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.