Jaka jest różnica między LPCSTR
, LPCTSTR
i LPTSTR
?
Dlaczego musimy to zrobić, aby przekonwertować ciąg na zmienną LV
/ _ITEM
structure pszText
:
LV_DISPINFO dispinfo;
dispinfo.item.pszText = LPTSTR((LPCTSTR)string);
c++
windows
visual-c++
mfc
nicMaster
źródło
źródło
Odpowiedzi:
Aby odpowiedzieć na pierwszą część pytania:
LPCSTR
jest wskaźnikiem na ciąg znaków const (LP oznacza długi wskaźnik )LPCTSTR
jest wskaźnikiem doconst TCHAR
łańcucha (TCHAR
będącego szerokim znakiem lub znakiem w zależności od tego, czy w projekcie zdefiniowano UNICODE)LPTSTR
jest wskaźnikiem do (nie stałego)TCHAR
ciąguW praktyce, kiedy mówiliśmy o nich w przeszłości, pominęliśmy „wskaźnik do” wyrażenia dla uproszczenia, ale jak wspomniano w lekkich wyścigach na orbicie, wszystkie one są wskazówkami.
To jest świetny artykuł o projekcie kodu opisujący ciągi C ++ (patrz 2/3 drogi w dół, aby zobaczyć wykres porównujący różne typy)
źródło
extern "C"
. Poza tym, tak, zdecydowanie powinien potrzebować bitu „wskaźnika” lub konkretnego opisu jako napisu w C.Szybko i brudno:
LP
== L ong P ointer. Po prostu pomyśl o wskaźniku lub znaku *C
= C onst, w tym przypadku myślę, że oznaczają one ciąg znaków, a nie wskaźnik będący stałą.STR
jest ciągiemT
jest dla szerokiego znaku lub char (TCHAR) w zależności od opcji kompilacji.źródło
8-bitowe AnsiStrings
char
: Znak 8-bitowy - podstawowy typ danych C / C ++CHAR
: aliaschar
- typ danych WindowsLPSTR
: zakończony zerem ciągCHAR
( L ong P ointer)LPCSTR
: stały ciąg zakończony zeremCHAR
( L ong P ointer)16-bitowe UnicodeStrings
wchar_t
: Znak 16-bitowy - podstawowy typ danych C / C ++WCHAR
: aliaswchar_t
- typ danych WindowsLPWSTR
: zakończony zerem ciągWCHAR
( L ong P ointer)LPCWSTR
: stały ciąg zakończony zeremWCHAR
( L ong P ointer)w zależności od
UNICODE
zdefiniowaniaTCHAR
: aliasWCHAR
jeśli zdefiniowano UNICODE; InaczejCHAR
LPTSTR
: zakończony zerem ciągTCHAR
( L ong P ointer)LPCTSTR
: stały ciąg zakończony zeremTCHAR
( L ong P ointer)Więc
Czytanie bonusowe
TCHAR
→ Tekst Char ( archive.is )źródło
Dodawanie do odpowiedzi Johna i Tima.
Jeśli nie piszesz dla Win98, istnieją tylko dwa z ponad 6 typów ciągów, których powinieneś używać w swojej aplikacji
LPWSTR
LPCWSTR
Reszta jest przeznaczona do obsługi platform ANSI lub podwójnych kompilacji. Nie są one dziś tak aktualne, jak kiedyś.
źródło
std::string
ponieważ nadal jest to ciąg oparty na ASCII i wolęstd::wstring
zamiast tego.*A
dostosowaniem wersji WinAPI do strony kodowej UTF-8, nagle stają się one znacznie bardziej odpowiednie. ; PAby odpowiedzieć na drugą część pytania, musisz wykonać takie czynności jak
ponieważ
LVITEM
struktura MS ma plikLPTSTR
, tj. zmienny wskaźnik łańcucha T, a nieLPCTSTR
. To, co robisz, jest1) przekonwertować
string
(CString
przypuszczalnie a) naLPCTSTR
(co w praktyce oznacza uzyskanie adresu bufora znaków jako wskaźnika tylko do odczytu)2) przekonwertować ten wskaźnik tylko do odczytu na wskaźnik z możliwością zapisu, odrzucając jego
const
-ness.Zależy to od tego, co
dispinfo
zostanie użyte do tego, czy jest szansa, że twojaListView
rozmowa zakończy się próbą napisania przez topszText
. Jeśli tak, jest to potencjalnie bardzo zła rzecz: w końcu otrzymałeś wskaźnik tylko do odczytu i zdecydowałeś traktować go jako zapisywalny: może jest powód, dla którego był on tylko do odczytu!Jeśli jest to plik, z
CString
którym pracujesz, masz możliwość użyciastring.GetBuffer()
- to celowo daje ci możliwość zapisuLPTSTR
. Musisz wtedy pamiętać o wywołaniu,ReleaseBuffer()
jeśli łańcuch się zmieni. Lub możesz przydzielić lokalny bufor tymczasowy i skopiować tam ciąg.W 99% przypadków będzie to niepotrzebne i traktowanie tego
LPCTSTR
jakoLPTSTR
dobrego zadziała ... ale pewnego dnia, kiedy najmniej się tego spodziewasz ...źródło
xxx_cast<>()
zamiast tego używać .xxx_cast<>
zamiast mieszania dwóch różnych stylów rzutowania opartych na nawiasach!