Lo que la diferencia entre LPCSTR
, LPCTSTR
y LPTSTR
?
¿Por qué necesitamos hacer esto para convertir una cadena en una variable de estructura LV
/ ? _ITEM
pszText
LV_DISPINFO dispinfo;
dispinfo.item.pszText = LPTSTR((LPCTSTR)string);
Lo que la diferencia entre LPCSTR
, LPCTSTR
y LPTSTR
?
¿Por qué necesitamos hacer esto para convertir una cadena en una variable de estructura LV
/ ? _ITEM
pszText
LV_DISPINFO dispinfo;
dispinfo.item.pszText = LPTSTR((LPCTSTR)string);
Respuestas:
Para responder a la primera parte de su pregunta:
LPCSTR
es un puntero a una cadena constante (LP significa Long Pointer )
LPCTSTR
es un puntero a una const TCHAR
cadena, (puede TCHAR
ser un char ancho o char dependiendo de si UNICODE está definido en su proyecto)
LPTSTR
es un puntero a una TCHAR
cadena (no constante)
En la práctica, cuando hablamos de estos en el pasado, hemos omitido la frase "puntero a una" por simplicidad, pero como se menciona en Lightness-Race-in-Orbit, todos son indicadores.
Este es un gran artículo de proyecto de código que describe cadenas de C ++ (consulte 2/3 en el camino hacia abajo para ver un gráfico que compara los diferentes tipos)
extern "C"
. Aparte de eso, sí, definitivamente debería necesitar el bit de "puntero" o una descripción específica como una cadena C.
Rápido y sucio:
LP
== L ong P ointer. Solo piensa en puntero o char *
C
= C onst, en este caso, creo que quieren decir que la cadena de caracteres es una constante, no que el puntero sea constante.
STR
es una cuerda
el T
es de un carácter ancho o char (TCHAR) dependiendo de las opciones de compilación.
char
: Carácter de 8 bits - tipo de datos C / C ++ subyacenteCHAR
: alias de char
- tipo de datos de WindowsLPSTR
: cadena terminada en nulo de CHAR
( L ong P ointer)LPCSTR
: cadena constante terminada en nulo de CHAR
( L ong P ointer)wchar_t
: Carácter de 16 bits - tipo de datos C / C ++ subyacenteWCHAR
: alias de wchar_t
- tipo de datos de WindowsLPWSTR
: cadena terminada en nulo de WCHAR
( L ong P ointer)LPCWSTR
: cadena constante terminada en nulo de WCHAR
( L ong P ointer)UNICODE
definirTCHAR
: alias de WCHAR
si se define UNICODE; de otra maneraCHAR
LPTSTR
: cadena terminada en nulo de TCHAR
( L ong P ointer)LPCTSTR
: cadena constante terminada en nulo de TCHAR
( L ong P ointer)Entonces
| Item | 8-bit | 16-bit | Varies |
|-------------------|--------------|-------------|-----------------|
| character | CHAR | WCHAR | TCHAR |
| string | LPSTR | LPWSTR | LPTSTR |
| string (const) | LPCSTR | LPCWSTR | LPCTSTR |
TCHAR
→ Texto Char ( archive.is )
Añadiendo a la respuesta de John y Tim.
A menos que esté codificando para Win98, solo hay dos de los más de 6 tipos de cadenas que debe usar en su aplicación
LPWSTR
LPCWSTR
El resto está destinado a admitir plataformas ANSI o compilaciones duales. Esos no son tan relevantes hoy como solían ser.
std::string
porque sigue siendo una cadena basada en ASCII y prefiero en su std::wstring
lugar.
*A
versiones de WinAPI sean compatibles con la página de códigos UTF-8, de repente son mucho más relevantes. ; P
Para responder a la segunda parte de su pregunta, debe hacer cosas como
LV_DISPINFO dispinfo;
dispinfo.item.pszText = LPTSTR((LPCTSTR)string);
porque la LVITEM
estructura de MS tiene LPTSTR
, es decir, un puntero de cadena T mutable , no un LPCTSTR
. Lo que estas haciendo es
1) convertir string
(a CString
en una suposición) en unLPCTSTR
(que en la práctica significa obtener la dirección de su búfer de caracteres como un puntero de solo lectura)
2) convierta ese puntero de solo lectura en un puntero escribible const
desechando su carácter -ness.
Depende de lo que dispinfo
se use para saber si existe la posibilidad de que su ListView
llamada termine intentando escribir a través de eso pszText
. Si lo hace, esto es algo potencialmente muy malo: después de todo, se le dio un puntero de solo lectura y luego decidió tratarlo como escribible: ¡quizás haya una razón por la que era de solo lectura!
Si está CString
trabajando con él, tiene la opción de usarlo string.GetBuffer()
, que deliberadamente le da una escritura LPTSTR
. Entonces tienes que recordar llamarReleaseBuffer()
si la cadena se cambia. O puede asignar un búfer temporal local y copiar la cadena allí.
El 99% de las veces esto será innecesario y tratarlo LPCTSTR
como un LPTSTR
testamento funcionará ... pero un día, cuando menos lo esperes ...
xxx_cast<>()
en su lugar.
xxx_cast<>
lugar de mezclar dos estilos de fundición diferentes basados en corchetes.