LPCSTR, LPCTSTR en LPTSTR

Wat is het verschil tussen LPCSTR, LPCTSTRen LPTSTR?

Waarom moeten we dit doen om een ​​string om te zetten in een LV/ _ITEMstructuurvariabele pszText:

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

Antwoord 1, autoriteit 100%

Om het eerste deel van uw vraag te beantwoorden:

LPCSTRis een verwijzing naar een const-tekenreeks (LP betekent Lang Aanwijzer)

LPCTSTRis een verwijzing naar een const TCHAR-tekenreeks, (TCHARis ofwel een brede char of char, afhankelijk van of UNICODE is gedefinieerd in uw project)

LPTSTRis een verwijzing naar een (niet-const) TCHAR-tekenreeks

In de praktijk hebben we, als we hier in het verleden over spraken, de term ‘aanwijzer naar een’ voor de eenvoud weggelaten, maar zoals vermeld door lightness-races-in-orbit zijn het allemaal wijzers.

Dit is een geweldig codeproject-artikeldat C++-strings beschrijft (zie 2/3 de weg naar beneden voor een grafiek die de verschillende typen vergelijkt)


Antwoord 2, autoriteit 71%

Snel en vuil:

LP== Long Pointer. Denk maar aan pointer of char*

C= Const, in dit geval denk ik dat ze bedoelen dat de tekenreeks een const is, niet dat de aanwijzer const is.

STRis tekenreeks

de Tis voor een breed teken of char (TCHAR), afhankelijk van de compileropties.

Bonuslezen

Van Waar staat de letter “T” in LPTSTR voor?: archief

Waar staat de letter “T” in LPTSTR voor?

17 oktober 2006

De “T” in LPTSTR komt van de “T” in TCHAR. Ik weet het niet zeker, maar het lijkt vrij waarschijnlijk dat het staat voor “tekst”. Ter vergelijking: de “W” in WCHAR komt waarschijnlijk van de C-taalstandaard, waar het staat voor “wide”.


Antwoord 3, autoriteit 41%

8-bits AnsiStrings

  • CHAR: 8-bits teken (onderliggend C/C++-gegevenstype)
  • CHAR: alias van CHAR(Windows-gegevenstype)
  • LPSTR: null-terminated string van CHAR(Long Pointer)
  • LPCSTR: constante null-terminated string van CHAR(Long Pointer Conmiddellijk)

16-bits UnicodeStrings

  • wchar_t: 16-bits teken (onderliggend C/C++-gegevenstype)
  • WCHAR: alias van wchar_t(Windows-gegevenstype)
  • LPWSTR: null-terminated string van WCHAR(Long Pointer)
  • LPCWSTR: constante null-terminated string van WCHAR(Long Pointer Conmiddellijk)

afhankelijk van UNICODEdefiniëren

  • TCHAR: alias van WCHARals UNICODE is gedefinieerd; anders CHAR
  • LPTSTR: null-terminated string van TCHAR(Long Pointer)
  • LPCTSTR: constante null-terminated string van TCHAR(Long Pointer Conmiddellijk)

Dus:

Artikel 8-bits (Ansi) 16-bits (Breed) Varieert
karakter CHAR WCHAR TCHAR
tekenreeks LPSTR LPWSTR LPTSTR
string (const) LPCSTR LPCWSTR LPCTSTR

Antwoord 4, autoriteit 5%

Toevoegen aan het antwoord van John en Tim.

Tenzij u codeert voor Win98, zijn er slechts twee van de 6+ stringtypes die u in uw toepassing zou moeten gebruiken

  • LPWSTR
  • LPCWSTR

De rest is bedoeld om ANSI-platforms of dubbele compilaties te ondersteunen. Die zijn tegenwoordig niet meer zo relevant als vroeger.


Antwoord 5, autoriteit 3%

Om het tweede deel van uw vraag te beantwoorden, moet u dingen doen als

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

omdat de LVITEM-struct van MS een LPTSTRheeft, dwz een veranderlijkeT-string-aanwijzer, niet een LPCTSTR. Wat je doet is

1) converteer string(een CStringnaar schatting) naar een LPCTSTR(wat in de praktijk betekent dat je het adres van zijn karakterbuffer krijgt als alleen-lezen-aanwijzer)

2) zet die alleen-lezen-aanwijzer om in een beschrijfbare aanwijzer door zijn const-heid weg te gooien.

Het hangt ervan af waarvoor dispinfowordt gebruikt of er een kans is dat uw ListView-aanroep uiteindelijk probeert om te schrijvenvia dat pszText. Als dit het geval is, is dit een potentieel zeer slechte zaak: u kreeg tenslotte een alleen-lezen-aanwijzer en besloot deze als beschrijfbaar te behandelen: misschien is er een reden dat het alleen-lezen was!

Als het een CStringis waarmee u werkt, heeft u de mogelijkheid om string.GetBuffer()te gebruiken — dat geeft u opzettelijk een beschrijfbare LPTSTR. U moet dan onthouden om ReleaseBuffer()aan te roepen als de tekenreeks wordt gewijzigd. Of je kunt een lokale tijdelijke buffer toewijzen en de string daar naartoe kopiëren.

99% van de tijd zal dit niet nodig zijn en de LPCTSTRbehandelen als een LPTSTRzal werken… maar op een dag, wanneer je het het minst verwacht…


Antwoord 6

Het korte antwoord op het tweede deel van de vraag is eenvoudigweg dat de klasse CStringgeen directe typecast-conversie biedt door het ontwerp en wat je doet is een soort van valsspelen.

Een langer antwoord is het volgende:

De reden dat u CStringnaar LPCTSTRkunt typen, is omdat CString deze mogelijkheid biedt door operator=te overschrijven. Door het ontwerp biedt het conversie naar alleen de LPCTSTR-aanwijzer, zodat de tekenreekswaarde niet kan worden gewijzigd met deze aanwijzer.

Met andere woorden, het levert gewoon geen overbelasting operator=op om de CStringom te zetten in LPSTRom dezelfde reden als hierboven . Ze willen niet toestaan ​​dat de tekenreekswaarde op deze manier wordt gewijzigd.

Dus in wezen is de truc om de operator CString offer te gebruiken en dit te krijgen:

LPTSTR lptstr = (LPCTSTR) string; // CString provide this operator overload

LPTSTR kan nu verder worden getypecast naar LPSTR 🙂

dispinfo.item.pszText = LPTSTR( lpfzfd); // accomplish the cheat :P

De juiste manier om LPTSTRvan ‘CString’ te krijgen is echter deze (compleet voorbeeld):

CString str = _T("Hello");
LPTSTR lpstr = str.GetBuffer(str.GetAllocLength());
str.ReleaseBuffer(); // you must call this function if you change the string above with the pointer

Nogmaals omdat de GetBuffer()retourneert LPTSTRom die reden die je nu kunt wijzigen 🙂

Other episodes