Quale la differenza tra LPCSTR
, LPCTSTR
e LPTSTR
?
Perché è necessario farlo per convertire una stringa in una variabile di struttura LV
/ : _ITEM
pszText
LV_DISPINFO dispinfo;
dispinfo.item.pszText = LPTSTR((LPCTSTR)string);
Quale la differenza tra LPCSTR
, LPCTSTR
e LPTSTR
?
Perché è necessario farlo per convertire una stringa in una variabile di struttura LV
/ : _ITEM
pszText
LV_DISPINFO dispinfo;
dispinfo.item.pszText = LPTSTR((LPCTSTR)string);
Risposte:
Per rispondere alla prima parte della tua domanda:
LPCSTR
è un puntatore a una stringa const (LP significa Long Pointer )
LPCTSTR
è un puntatore a una const TCHAR
stringa, ( TCHAR
essendo un carattere ampio o un carattere a seconda che UNICODE sia definito nel progetto)
LPTSTR
è un puntatore a una TCHAR
stringa (non const)
In pratica, parlando di questi in passato, abbiamo tralasciato la frase "pointer to a" per semplicità, ma come accennato da lightness-race-in-orbit sono tutti indicatori.
Questo è un ottimo articolo sul progetto di codice che descrive le stringhe C ++ (vedi 2/3 fino in fondo per un grafico che confronta i diversi tipi)
extern "C"
. A parte questo, sì, dovrebbe sicuramente aver bisogno del bit "pointer" o di una descrizione specifica come stringa C.
Veloce e sporco:
LP
== L ong P ointer. Pensa solo a pointer o char *
C
= C onst, in questo caso, penso che significhino che la stringa di caratteri è una const, non il puntatore che è const.
STR
è una stringa
la T
è per una vasta carattere o char (TCHAR) a seconda delle opzioni di compilazione.
char
: Carattere a 8 bit - tipo di dati C / C ++ sottostanteCHAR
: alias di char
- Tipo di dati WindowsLPSTR
: stringa con terminazione null di CHAR
( L ong P ointer)LPCSTR
: stringa costante con terminazione null di CHAR
( L ong P ointer)wchar_t
: Carattere a 16 bit - tipo di dati C / C ++ sottostanteWCHAR
: alias di wchar_t
- Tipo di dati WindowsLPWSTR
: stringa con terminazione null di WCHAR
( L ong P ointer)LPCWSTR
: stringa costante con terminazione null di WCHAR
( L ong P ointer)UNICODE
definireTCHAR
: alias di WCHAR
se UNICODE è definito; altrimentiCHAR
LPTSTR
: stringa con terminazione null di TCHAR
( L ong P ointer)LPCTSTR
: stringa costante con terminazione null di TCHAR
( L ong P ointer)Così
| Item | 8-bit | 16-bit | Varies |
|-------------------|--------------|-------------|-----------------|
| character | CHAR | WCHAR | TCHAR |
| string | LPSTR | LPWSTR | LPTSTR |
| string (const) | LPCSTR | LPCWSTR | LPCTSTR |
TCHAR
→ Carattere testo ( archive.is )
In aggiunta alla risposta di John e Tim.
A meno che tu non stia codificando per Win98, ci sono solo due dei 6+ tipi di stringhe che dovresti usare nella tua applicazione
LPWSTR
LPCWSTR
Il resto ha lo scopo di supportare piattaforme ANSI o compilazioni doppie. Quelle non sono più rilevanti oggi come una volta.
std::string
perché è ancora una stringa basata su ASCII e preferisco std::wstring
invece.
*A
versioni di WinAPI compatibili con la code page UTF-8, sono improvvisamente molto più rilevanti. ; P
Per rispondere alla seconda parte della tua domanda, devi fare cose come
LV_DISPINFO dispinfo;
dispinfo.item.pszText = LPTSTR((LPCTSTR)string);
perché MS LVITEM
struttura ha una LPTSTR
, cioè un mutevole puntatore T-stringa, non un LPCTSTR
. Quello che stai facendo è
1) converti string
( CString
a indovinare) in an LPCTSTR
(che in pratica significa ottenere l'indirizzo del suo buffer di caratteri come puntatore di sola lettura)
2) converti quel puntatore di sola lettura in un puntatore scrivibile gettando via la sua const
-ness.
Dipende da cosa dispinfo
viene utilizzato se c'è o meno la possibilità che la tua ListView
chiamata finisca per provare a scrivere attraverso quello pszText
. Se lo fa, questa è una cosa potenzialmente molto negativa: dopotutto ti è stato dato un puntatore di sola lettura e poi hai deciso di trattarlo come scrivibile: forse c'è una ragione per cui era di sola lettura!
Se è un con CString
cui stai lavorando, hai la possibilità di usare string.GetBuffer()
- questo ti dà deliberatamente un scrivibile LPTSTR
. Devi quindi ricordarti di chiamare ReleaseBuffer()
se la stringa viene modificata. Oppure puoi allocare un buffer temporaneo locale e copiare la stringa al suo interno.
Il 99% delle volte non sarà necessario e trattarlo LPCTSTR
come un LPTSTR
lavoro ... ma un giorno, quando meno te lo aspetti ...
xxx_cast<>()
invece.
xxx_cast<>
piuttosto che mescolare due diversi stili di casting basati su parentesi!