Яка різниця між 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; інакшеCHAR
LPTSTR
: Завершується нулем рядок 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+
LPWSTR
LPCWSTR
Решта призначені для підтримки платформ 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 CString
at здогадка) в LPCTSTR
(що на практиці означає отримати адресу свого буфера символів як покажчик лише для читання)
2) перетворити цей покажчик лише для читання у вказівник, що записується, відкинувши його const
-ness.
Це залежить від того, що dispinfo
використовується для того, чи існує ймовірність, що ваш ListView
дзвінок закінчиться спробою написати через це pszText
. Якщо це так, це потенційно дуже погано: адже вам дали вказівник лише для читання, а потім вирішили ставитися до нього як до запису: можливо, є причина, щоб він був лише для читання!
Якщо це CString
робота, з якою ви працюєте, у вас є можливість використовувати string.GetBuffer()
- це свідомо дає вам можливість запису LPTSTR
. Тоді вам слід пам'ятати, щоб зателефонувати, ReleaseBuffer()
якщо рядок все-таки змінився. Або ви можете виділити локальний тимчасовий буфер і скопіювати туди рядок.
У 99% випадків це буде непотрібним і поводження з LPCTSTR
ним LPTSTR
буде спрацьовувати ... але одного дня, коли ви найменше цього очікуєте ...
xxx_cast<>()
замість.
xxx_cast<>
а не змішування двох різних стилів кастингу на основі дужок!