2009-07-29 18 views
93

¿Cómo puedo convertir un std::string en LPCSTR? Además, ¿cómo puedo convertir un std::string en LPWSTR?Cómo convertir std :: string a LPCSTR?

estoy totalmente confundido con estas LPCSTRLPSTRLPWSTR y LPCWSTR.

Son LPWSTR y LPCWSTR lo mismo?

Respuesta

91

str.c_str() le da una const char *, que es un LPCSTR (puntero largo de cadena constante) - significa que es un puntero a una cadena de caracteres terminada 0. W significa cadena ancha (compuesta por wchar_t en lugar de char).

+5

Punto minúsculo: en x64 LPCSTR sería un puntero de 64 bits a una cadena (nula) terminada en nulo. – Joel

2

La conversión es simple:

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

138

llamada c_str() para conseguir un const char * (LPCSTR) de un std::string.

Está todo en el nombre:

LPSTR - (largo) puntero a la cadena - char *

LPCSTR - (largo) puntero a cadena constante - const char *

LPWSTR - (largo) puntero a Cadena Unicode (ancho) - wchar_t *

LPCWSTR - (largo) puntero a constante Unicode (ancho) string - const wchar_t *

LPTSTR - (largo) puntero a TCHAR (Unicode si UNICODE se define, ANSI si no) de cadena - TCHAR *

LPCTSTR - puntero (largo) a la cadena TCHAR constante - const TCHAR *

Usted puede ignorar la parte L (larga) de los nombres, es un remanente de Windows de 16 bits.

32

Estos son Microsoft typedefs definidos que corresponden a:

LPCSTR: puntero a cadena terminada en nulo const de char

LPSTR: puntero a null cadena Char terminado de char (a menudo un tampón se pasa y se utiliza como una 'salida' param)

LPCWSTR: puntero en null cadena terminada const wchar_t

LPWSTR: puntero a nulo t erminated cadena de wchar_t (a menudo se pasa un tampón y se utilizó como parámetro 'salida')

"convertir" a un std::string a un LPCSTR depende del contexto exacto, pero por lo general llamando .c_str() es suficiente.

Esto funciona.

void TakesString(LPCSTR param); 

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

Tenga en cuenta que no debe intentar hacer algo como esto.

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

El búfer devuelto por .c_str() es propiedad de la std::string instancia y sólo será válida hasta que la cuerda está próxima modificado o destruido.

Para convertir un std::string en un LPWSTR es más complicado. Querer un LPWSTR implica que necesita un búfer modificable y también necesita asegurarse de comprender qué codificación de caracteres está usando el std::string. Si el std::string contiene una cadena utilizando la codificación predeterminada del sistema (asumiendo ventanas, aquí), entonces puede encontrar la longitud del búfer de caracteres anchos requerido y realizar la transcodificación usando MultiByteToWideChar (una función API de Win32).

p. Ej.

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

de conversión es sencilla:

std::string myString; 

LPCSTR lpMyString = myString.c_str(); 

Una cosa a tener cuidado de aquí es que c_str no devuelve una copia de miCadena, pero sólo un puntero a la cadena de caracteres que std :: string envolturas . Si quieres/necesitas una copia, deberás hacer una tú misma usando strcpy.

+0

Cómo convertir std :: String a LPWSTR ??? – Cute

1

La forma más fácil de convertir un std::string a un LPWSTR es en mi opinión:

  1. convertir el std::string a un std::vector<wchar_t>
  2. Tome la dirección de la primera wchar_t en el vector.

std::vector<wchar_t> tiene una ctor plantilla que tendrá dos iteradores, tales como los std::string.begin() y .end() iteradores. Esto convertirá cada char a wchar_t, sin embargo. Eso solo es válido si el std::string contiene ASCII o Latin-1, debido a la forma en que los valores Unicode se parecen a los valores Latin-1.Si contiene CP1252 o caracteres de cualquier otra codificación, es más complicado. Entonces necesitarás convertir los personajes.

14

Utilizando LPWSTR puede cambiar el contenido de la cadena donde apunta. Utilizando LPCWSTR no puede cambiar el contenido de la cadena a la que apunta.

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 es solo un puntero a la secuencia original. No debe devolverlo desde la función utilizando la muestra anterior. Para obtener LPWSTR temporal, debe hacer una copia de la cadena original en el montón. Compruebe el ejemplo siguiente:

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

El MultiByteToWideChar respuesta que dio Charles Bailey es la correcta. Como LPCWSTR es simplemente un typedef para const WCHAR*, widestr en el código de ejemplo, se puede usar donde se espera LPWSTR o donde se espera LPCWSTR.

Un pequeño ajuste sería utilizar std::vector<WCHAR> en lugar de una matriz administrada de forma manual:

// 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 

Además, si es necesario trabajar con las cadenas de ancho, para empezar, se puede utilizar en lugar de std::wstringstd::string. Si desea trabajar con el tipo de Windows TCHAR, puede usar std::basic_string<TCHAR>. La conversión de std::wstring a LPCWSTR o de std::basic_string<TCHAR> a LPCTSTR es solo una cuestión de llamar al c_str. Es cuando cambia entre caracteres ANSI y UTF-16 que MultiByteToWideChar (y su inverso WideCharToMultiByte) entra en escena.

Cuestiones relacionadas