Was ist der Unterschied zwischen LPCSTR
, LPCTSTR
und LPTSTR
?
Warum müssen wir dies tun, um einen String in eine LV
/ _ITEM
Strukturvariable zu konvertieren pszText
:
LV_DISPINFO dispinfo;
dispinfo.item.pszText = LPTSTR((LPCTSTR)string);
Was ist der Unterschied zwischen LPCSTR
, LPCTSTR
und LPTSTR
?
Warum müssen wir dies tun, um einen String in eine LV
/ _ITEM
Strukturvariable zu konvertieren pszText
:
LV_DISPINFO dispinfo;
dispinfo.item.pszText = LPTSTR((LPCTSTR)string);
Antworten:
So beantworten Sie den ersten Teil Ihrer Frage:
LPCSTR
ist ein Zeiger auf eine konstante Zeichenfolge (LP bedeutet Long Pointer )
LPCTSTR
ist ein Zeiger auf eine const TCHAR
Zeichenfolge ( TCHAR
entweder ein breites Zeichen oder ein Zeichen, je nachdem, ob UNICODE in Ihrem Projekt definiert ist).
LPTSTR
ist ein Zeiger auf eine (nicht konstante) TCHAR
Zeichenfolge
In der Praxis haben wir, wenn wir in der Vergangenheit darüber gesprochen haben, der Einfachheit halber den "Zeiger auf eine" Phrase weggelassen, aber wie von Leichtigkeitsrennen im Orbit erwähnt, sind sie alle Zeiger.
Dies ist ein großartiger Codeprojekt-Artikel , der C ++ - Zeichenfolgen beschreibt (siehe 2/3 unten für ein Diagramm, in dem die verschiedenen Typen verglichen werden).
extern "C"
. Abgesehen davon sollte es definitiv entweder das "Zeiger" -Bit oder eine spezifische Beschreibung als C-Zeichenfolge benötigen.
Schnell und dreckig:
LP
== L ong P ointer. Denken Sie nur an Zeiger oder Zeichen *
C
= C onst, in diesem Fall denke ich, dass die Zeichenfolge eine Konstante ist, nicht der Zeiger eine Konstante.
STR
ist Zeichenfolge
das T
ist für ein breites Zeichen oder Zeichen (TCHAR) , je nach Kompilierungsoptionen.
char
: 8-Bit-Zeichen - zugrunde liegender C / C ++ - DatentypCHAR
: Alias von char
- Windows-DatentypLPSTR
: nullterminierte Zeichenfolge von CHAR
( L ong P ointer)LPCSTR
: Konstante nullterminierte Zeichenfolge von CHAR
( L ong P ointer)wchar_t
: 16-Bit-Zeichen - zugrunde liegender C / C ++ - DatentypWCHAR
: Alias von wchar_t
- Windows-DatentypLPWSTR
: nullterminierte Zeichenfolge von WCHAR
( L ong P ointer)LPCWSTR
: Konstante nullterminierte Zeichenfolge von WCHAR
( L ong P ointer)UNICODE
definierenTCHAR
: Alias von WCHAR
wenn UNICODE definiert ist; AndernfallsCHAR
LPTSTR
: nullterminierte Zeichenfolge von TCHAR
( L ong P ointer)LPCTSTR
: Konstante nullterminierte Zeichenfolge von TCHAR
( L ong P ointer)So
| Item | 8-bit | 16-bit | Varies |
|-------------------|--------------|-------------|-----------------|
| character | CHAR | WCHAR | TCHAR |
| string | LPSTR | LPWSTR | LPTSTR |
| string (const) | LPCSTR | LPCWSTR | LPCTSTR |
TCHAR
→ Text Char ( archive.is )
Hinzufügen zu Johns und Tims Antwort.
Sofern Sie nicht für Win98 codieren, gibt es nur zwei der mehr als 6 Zeichenfolgentypen, die Sie in Ihrer Anwendung verwenden sollten
LPWSTR
LPCWSTR
Der Rest soll ANSI-Plattformen oder Dual-Compilations unterstützen. Diese sind heute nicht mehr so relevant wie früher.
std::string
weil es immer noch eine ASCII-basierte Zeichenfolge ist und std::wstring
stattdessen bevorzugen .
*A
Versionen von WinAPI mit der UTF-8-Codepage kompatibel zu machen, sind sie plötzlich viel relevanter. ; P
Um den zweiten Teil Ihrer Frage zu beantworten, müssen Sie Dinge wie tun
LV_DISPINFO dispinfo;
dispinfo.item.pszText = LPTSTR((LPCTSTR)string);
weil die LVITEM
Struktur von MS einen LPTSTR
, dh einen veränderlichen T-String-Zeiger hat, keinen LPCTSTR
. Was Sie tun, ist
1) konvertiere string
(a CString
a rate) in a LPCTSTR
(was in der Praxis bedeutet, die Adresse seines Zeichenpuffers als schreibgeschützten Zeiger zu erhalten)
2) Konvertieren Sie diesen schreibgeschützten Zeiger in einen beschreibbaren Zeiger, indem Sie seine const
-ness wegwerfen.
Es hängt davon ab, wofür verwendet dispinfo
wird, ob die Möglichkeit besteht, dass Ihr ListView
Anruf versucht , dies durchzuschreiben pszText
. Wenn dies der Fall ist, ist dies möglicherweise eine sehr schlechte Sache: Schließlich haben Sie einen schreibgeschützten Zeiger erhalten und dann beschlossen, ihn als beschreibbar zu behandeln: Vielleicht gibt es einen Grund, warum er schreibgeschützt war!
Wenn es ein CString
ist, mit dem Sie arbeiten, haben Sie die Möglichkeit zu verwenden string.GetBuffer()
- das gibt Ihnen absichtlich eine beschreibbare LPTSTR
. Sie müssen dann daran denken, aufzurufen, ReleaseBuffer()
wenn die Zeichenfolge geändert wird. Oder Sie können einen lokalen temporären Puffer zuweisen und die Zeichenfolge dort kopieren.
99% der Zeit wird dies unnötig sein und die Behandlung LPCTSTR
als ein LPTSTR
Wille funktionieren ... aber eines Tages, wenn Sie es am wenigsten erwarten ...
xxx_cast<>()
stattdessen verwenden.
xxx_cast<>
zwei verschiedene klammerbasierte Casting-Stile verwendet, anstatt sie zu mischen!