Jaka jest różnica między LPCSTR, LPCTSTRi LPTSTR?
Dlaczego musimy to zrobić, aby przekonwertować ciąg na zmienną LV/ _ITEMstructure pszText:
LV_DISPINFO dispinfo;
dispinfo.item.pszText = LPTSTR((LPCTSTR)string);
Jaka jest różnica między LPCSTR, LPCTSTRi LPTSTR?
Dlaczego musimy to zrobić, aby przekonwertować ciąg na zmienną LV/ _ITEMstructure pszText:
LV_DISPINFO dispinfo;
dispinfo.item.pszText = LPTSTR((LPCTSTR)string);
Odpowiedzi:
Aby odpowiedzieć na pierwszą część pytania:
LPCSTRjest wskaźnikiem na ciąg znaków const (LP oznacza długi wskaźnik )
LPCTSTRjest wskaźnikiem do const TCHARłańcucha ( TCHARbędącego szerokim znakiem lub znakiem w zależności od tego, czy w projekcie zdefiniowano UNICODE)
LPTSTRjest wskaźnikiem do (nie stałego) TCHARciągu
W 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)
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łą.
STRjest ciągiem
Tjest dla szerokiego znaku lub char (TCHAR) w zależności od opcji kompilacji.
char: Znak 8-bitowy - podstawowy typ danych C / C ++CHAR: alias char- typ danych WindowsLPSTR: zakończony zerem ciąg CHAR ( L ong P ointer)LPCSTR: stały ciąg zakończony zerem CHAR ( L ong P ointer)wchar_t: Znak 16-bitowy - podstawowy typ danych C / C ++WCHAR: alias wchar_t- typ danych WindowsLPWSTR: zakończony zerem ciąg WCHAR ( L ong P ointer)LPCWSTR: stały ciąg zakończony zerem WCHAR ( L ong P ointer)UNICODEzdefiniowaniaTCHAR: alias WCHARjeśli zdefiniowano UNICODE; InaczejCHARLPTSTR: zakończony zerem ciąg TCHAR ( L ong P ointer)LPCTSTR: stały ciąg zakończony zerem TCHAR ( L ong P ointer)Więc
| Item | 8-bit | 16-bit | Varies |
|-------------------|--------------|-------------|-----------------|
| character | CHAR | WCHAR | TCHAR |
| string | LPSTR | LPWSTR | LPTSTR |
| string (const) | LPCSTR | LPCWSTR | LPCTSTR |
TCHAR→ Tekst Char ( archive.is )
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
LPWSTRLPCWSTRReszta jest przeznaczona do obsługi platform ANSI lub podwójnych kompilacji. Nie są one dziś tak aktualne, jak kiedyś.
std::stringponieważ nadal jest to ciąg oparty na ASCII i wolę std::wstringzamiast tego.
*Adostosowaniem wersji WinAPI do strony kodowej UTF-8, nagle stają się one znacznie bardziej odpowiednie. ; P
Aby odpowiedzieć na drugą część pytania, musisz wykonać takie czynności jak
LV_DISPINFO dispinfo;
dispinfo.item.pszText = LPTSTR((LPCTSTR)string);
ponieważ LVITEMstruktura MS ma plikLPTSTR , tj. zmienny wskaźnik łańcucha T, a nie LPCTSTR. To, co robisz, jest
1) przekonwertować string( CStringprzypuszczalnie a) na LPCTSTR(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 dispinfozostanie użyte do tego, czy jest szansa, że twoja ListViewrozmowa zakończy się próbą napisania przez to pszText. 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 CStringktórym pracujesz, masz możliwość użycia string.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 LPCTSTRjako LPTSTRdobrego zadziała ... ale pewnego dnia, kiedy najmniej się tego spodziewasz ...
xxx_cast<>()zamiast tego używać .
xxx_cast<>zamiast mieszania dwóch różnych stylów rzutowania opartych na nawiasach!