Qual é a diferença entre LPCSTR
, LPCTSTR
e LPTSTR
?
Por que precisamos fazer isso para converter uma string em uma variável LV
/ _ITEM
structure pszText
:
LV_DISPINFO dispinfo;
dispinfo.item.pszText = LPTSTR((LPCTSTR)string);
Qual é a diferença entre LPCSTR
, LPCTSTR
e LPTSTR
?
Por que precisamos fazer isso para converter uma string em uma variável LV
/ _ITEM
structure pszText
:
LV_DISPINFO dispinfo;
dispinfo.item.pszText = LPTSTR((LPCTSTR)string);
Respostas:
Para responder à primeira parte da sua pergunta:
LPCSTR
é um ponteiro para uma string const (LP significa Ponteiro Longo )
LPCTSTR
é um ponteiro para uma const TCHAR
string ( TCHAR
sendo um caractere largo ou caractere dependendo se UNICODE está definido em seu projeto)
LPTSTR
é um ponteiro para uma TCHAR
string (não const)
Na prática, quando falamos sobre isso no passado, deixamos de fora a frase "ponteiro para" para simplificar, mas, como mencionado pelas corridas de leveza em órbita, todos são ponteiros.
Este é um ótimo artigo de projeto de código que descreve strings C ++ (consulte 2/3 abaixo para ver um gráfico comparando os diferentes tipos)
extern "C"
. Além disso, sim, ele definitivamente deve precisar do bit "ponteiro" ou de uma descrição específica como uma string C.
Rapido e sujo:
LP
== L ong P ointer. Basta pensar em ponteiro ou char *
C
= C onst, neste caso, acho que eles significam que a string de caracteres é uma const, e não o ponteiro sendo const.
STR
é string
o T
é para uma grande personagem ou char (TCHAR), dependendo das opções de compilação.
char
: Caractere de 8 bits - tipo de dados C / C ++ subjacenteCHAR
: alias de char
- tipo de dados do WindowsLPSTR
: string terminada em nulo de CHAR
( L ong P ointer)LPCSTR
: string constante terminada em nulo de CHAR
( L ong P ointer)wchar_t
: Caractere de 16 bits - tipo de dados C / C ++ subjacenteWCHAR
: alias de wchar_t
- tipo de dados do WindowsLPWSTR
: string terminada em nulo de WCHAR
( L ong P ointer)LPCWSTR
: string constante terminada em nulo de WCHAR
( L ong P ointer)UNICODE
definirTCHAR
: alias de WCHAR
se UNICODE for definido; de outra formaCHAR
LPTSTR
: string terminada em nulo de TCHAR
( L ong P ointer)LPCTSTR
: string constante terminada em nulo de TCHAR
( L ong P ointer)assim
| Item | 8-bit | 16-bit | Varies |
|-------------------|--------------|-------------|-----------------|
| character | CHAR | WCHAR | TCHAR |
| string | LPSTR | LPWSTR | LPTSTR |
| string (const) | LPCSTR | LPCWSTR | LPCTSTR |
TCHAR
→ Caractere de texto ( arquivo.is )
Somando-se à resposta de John e Tim.
A menos que você esteja codificando para Win98, existem apenas dois dos mais de 6 tipos de string que você deve usar em seu aplicativo
LPWSTR
LPCWSTR
O restante destina-se a suportar plataformas ANSI ou compilações duplas. Esses não são tão relevantes hoje como costumavam ser.
std::string
porque ainda é uma string baseada em ASCII e prefiro std::wstring
.
*A
versões do WinAPI compatíveis com a página de código UTF-8, de repente elas são muito mais relevantes. ; P
Para responder à segunda parte da sua pergunta, você precisa fazer coisas como
LV_DISPINFO dispinfo;
dispinfo.item.pszText = LPTSTR((LPCTSTR)string);
porque a LVITEM
estrutura de MS tem um LPTSTR
, ou seja, um ponteiro mutável de string T, não um LPCTSTR
. O que você está fazendo é
1) converter string
(a CString
em um palpite) em um LPCTSTR
(o que na prática significa obter o endereço de seu buffer de caracteres como um ponteiro somente leitura)
2) converter aquele ponteiro somente leitura em um ponteiro gravável descartando sua const
-ness.
Depende do que dispinfo
é usado se há ou não uma chance de que sua ListView
chamada acabe tentando escrever através disso pszText
. Se isso acontecer, isso é potencialmente muito ruim: afinal, você recebeu um ponteiro somente leitura e decidiu tratá-lo como gravável: talvez haja um motivo pelo qual ele era somente leitura!
Se for um com o qual CString
você está trabalhando, você tem a opção de usar string.GetBuffer()
- isso deliberadamente dá a você um gravável LPTSTR
. Em seguida, você deve se lembrar de chamar ReleaseBuffer()
se a string for alterada. Ou você pode alocar um buffer temporário local e copiar a string para lá.
99% das vezes isso será desnecessário e tratá-los LPCTSTR
como um LPTSTR
funcionará ... mas um dia, quando você menos esperar ...
xxx_cast<>()
lugar.
xxx_cast<>
vez de misturar dois estilos de fundição baseados em colchetes diferentes!