Яка різниця між LPCSTR, LPCTSTRі LPTSTR?
Чому нам потрібно це зробити, щоб перетворити рядок у змінну LV/ _ITEMструктура pszText:
LV_DISPINFO dispinfo;
dispinfo.item.pszText = LPTSTR((LPCTSTR)string);
Яка різниця між LPCSTR, LPCTSTRі LPTSTR?
Чому нам потрібно це зробити, щоб перетворити рядок у змінну LV/ _ITEMструктура pszText:
LV_DISPINFO dispinfo;
dispinfo.item.pszText = LPTSTR((LPCTSTR)string);
Відповіді:
Щоб відповісти на першу частину вашого питання:
LPCSTRє вказівником на рядок const (LP означає Long Pointer )
LPCTSTRє вказівником на const TCHARрядок ( TCHARє широким знаком або знаком залежно від того, чи визначено UNICODE у вашому проекті)
LPTSTRє вказівником на TCHARрядок (не-const)
На практиці, коли ми говорили про це в минулому, ми залишили фразу "вказівник на" для простоти, але, як зазначає легкість перегонів на орбіті, вони всі покажчики.
Це чудова стаття з кодовим проектом, що описує рядки C ++ (див. Схему порівняння різних типів 2/3 вниз)
extern "C". Крім цього, так, це, безумовно, повинен мати або біт "покажчика", або конкретний опис у вигляді рядка C.
Швидкий і брудний:
LP== L Ong P ointer. Подумайте лише про вказівник чи шар *
C= C onst, в цьому випадку я думаю, що вони означають, що символьний рядок є const, а не покажчик const.
STRє рядок
значення Tдля широкого символу або знака (TCHAR) залежно від варіантів компіляції.
char: 8-бітний символ - базовий тип даних C / C ++CHAR: псевдонім char- тип даних WindowsLPSTR: Завершується нулем рядок CHAR ( L Ong P ointer)LPCSTR: Константа завершується нулем рядок CHAR ( L Ong P ointer)wchar_t: 16-бітний символ - базовий тип даних C / C ++WCHAR: псевдонім wchar_t- тип даних WindowsLPWSTR: Завершується нулем рядок WCHAR ( L Ong P ointer)LPCWSTR: Константа завершується нулем рядок WCHAR ( L Ong P ointer)UNICODEвизначенняTCHAR: псевдонім, WCHARякщо визначено UNICODE; інакшеCHARLPTSTR: Завершується нулем рядок TCHAR ( L Ong P ointer)LPCTSTR: Константа завершується нулем рядок TCHAR ( L Ong P ointer)Так
| Item | 8-bit | 16-bit | Varies |
|-------------------|--------------|-------------|-----------------|
| character | CHAR | WCHAR | TCHAR |
| string | LPSTR | LPWSTR | LPTSTR |
| string (const) | LPCSTR | LPCWSTR | LPCTSTR |
TCHAR→ Текстова діаграма ( archive.is )
Додавання відповіді Джона і Тіма.
Якщо ви не кодуєте Win98, у вашій програмі є лише два типи рядків 6+
LPWSTRLPCWSTRРешта призначені для підтримки платформ ANSI або подвійних компіляцій. Вони сьогодні не такі актуальні, як раніше.
std::stringтому що це все-таки рядок на основі ASCII і віддаю перевагу std::wstringзамість цього.
*Aверсії WinAPI сумісними з кодовою сторінкою UTF-8, вони раптом набагато актуальніші. ; P
Щоб відповісти на другу частину вашого питання, вам потрібно зробити такі речі
LV_DISPINFO dispinfo;
dispinfo.item.pszText = LPTSTR((LPCTSTR)string);
оскільки LVITEMструктура MS має LPTSTR, тобто змінний вказівник T-рядка, а не an LPCTSTR. Що ти робиш, так і є
1) перетворити string(a CStringat здогадка) в LPCTSTR(що на практиці означає отримати адресу свого буфера символів як покажчик лише для читання)
2) перетворити цей покажчик лише для читання у вказівник, що записується, відкинувши його const-ness.
Це залежить від того, що dispinfoвикористовується для того, чи існує ймовірність, що ваш ListViewдзвінок закінчиться спробою написати через це pszText. Якщо це так, це потенційно дуже погано: адже вам дали вказівник лише для читання, а потім вирішили ставитися до нього як до запису: можливо, є причина, щоб він був лише для читання!
Якщо це CStringробота, з якою ви працюєте, у вас є можливість використовувати string.GetBuffer()- це свідомо дає вам можливість запису LPTSTR. Тоді вам слід пам'ятати, щоб зателефонувати, ReleaseBuffer()якщо рядок все-таки змінився. Або ви можете виділити локальний тимчасовий буфер і скопіювати туди рядок.
У 99% випадків це буде непотрібним і поводження з LPCTSTRним LPTSTRбуде спрацьовувати ... але одного дня, коли ви найменше цього очікуєте ...
xxx_cast<>()замість.
xxx_cast<>а не змішування двох різних стилів кастингу на основі дужок!