LPCSTR, LPCTSTR y LPTSTR

¿Cuál es la diferencia entre LPCSTR , LPCTSTR y LPTSTR ?

¿Por qué tenemos que hacer esto para convertir una cadena en una variable de estructura LV / _ITEM pszText :

 LV_DISPINFO dispinfo; dispinfo.item.pszText = LPTSTR((LPCTSTR)string); 

Para responder la primera parte de su pregunta:

LPCSTR es una cadena const

LPCTSTR es una cadena const TCHAR , ( TCHAR es una char ancha o char dependiendo de si UNICODE está definido en su proyecto)

LPTSTR es una cadena TCHAR (no const)

Este es un gran artículo de proyecto de código que describe cadenas de C ++ (ver 2/3 el camino hacia abajo para un cuadro que compara los diferentes tipos)

Rápido y sucio:

LP == L ong P ointer. Solo piense en puntero o char *

C = C onst, en este caso, creo que significan que la cadena de caracteres es una const, no el puntero const.

STR es cadena

la T es para un carácter ancho o char (TCHAR) dependiendo de las opciones de comstackción.

AnsiStrings de 8 bits

  • char : char 8 bits – tipo de datos C / C ++ subyacente
  • CHAR : alias de char – tipo de datos de Windows
  • LPSTR : serie de CHAR terminada en nulo ( P onter de L ong)
  • LPCSTR : cadena de CHAR ( L ong P ointer) terminada en nulo constante

Cadenas Unicode de 16 bits

  • wchar_t : carácter de 16 bits: tipo de datos C / C ++ subyacente
  • WCHAR : alias de wchar_t – tipo de datos de Windows
  • LPWSTR : cadena de WCHAR terminada en nulo ( P onter de L ong)
  • LPCWSTR : cadena de WCHAR terminada en nulo constante ( P ointerro de L ong)

dependiendo de UNICODE define

  • TCHAR : alias de WCHAR si se define UNICODE; de lo contrario CHAR
  • LPTSTR : serie de TCHAR terminada en TCHAR ( P unor de L ong)
  • LPCTSTR : cadena de TCHAR terminada en nulo constante ( P uninterro de L ong)

Asi que

 | Item | 8-bit | 16-bit | Varies | |-------------------|--------------|-------------|-----------------| | character | CHAR | WCHAR | TCHAR | | string | LPSTR | LPWSTR | LPTSTR | | string (const) | LPCSTR | LPCWSTR | LPCTSTR | 

Lectura de bonificación

TCHARTexto Char

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 debería usar en su aplicación

  • LPWSTR
  • LPCWSTR

El rest está destinado a soportar plataformas ANSI o comstackciones duales. Esos hoy no son tan relevantes como solían ser.

Para responder la segunda parte de su pregunta, debe hacer cosas como

 LV_DISPINFO dispinfo; dispinfo.item.pszText = LPTSTR((LPCTSTR)string); 

porque la estructura LVITEM de MS tiene un LPTSTR , es decir, un puntero de cadena T mutable , no un LPCTSTR . Lo que estás haciendo es

1) convertir string (una CString en una conjetura) en un LPCTSTR (que en la práctica significa obtener la dirección de su buffer de caracteres como un puntero de solo lectura)

2) convertir ese puntero de solo lectura en un puntero escribible descartando su const -ness.

Depende de qué dispinfo se utilice para ver si existe o no la posibilidad de que su llamada a ListView termine tratando de escribir a través de ese pszText . Si lo hace, esto es algo potencialmente muy malo: después de todo, se te dio un puntero de solo lectura y luego decidiste tratarlo como escribible: ¡quizás haya una razón por la que fue de solo lectura!

Si se trata de un CString que está trabajando, tiene la opción de utilizar string.GetBuffer() – que le proporciona deliberadamente un LPTSTR escribible. Luego debe recordar llamar a ReleaseBuffer() 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 tratar el LPCTSTR como un LPTSTR funcionará … pero un día, cuando menos lo espere …