Какая разница между LPCSTR
, LPCTSTR
и LPTSTR
?
Зачем это нужно делать, чтобы преобразовать строку в переменную LV
/ _ITEM
structure pszText
:
LV_DISPINFO dispinfo;
dispinfo.item.pszText = LPTSTR((LPCTSTR)string);
Какая разница между LPCSTR
, LPCTSTR
и LPTSTR
?
Зачем это нужно делать, чтобы преобразовать строку в переменную LV
/ _ITEM
structure pszText
:
LV_DISPINFO dispinfo;
dispinfo.item.pszText = LPTSTR((LPCTSTR)string);
Ответы:
Чтобы ответить на первую часть вашего вопроса:
LPCSTR
указатель на константную строку (LP означает длинный указатель )
LPCTSTR
является указателем на const TCHAR
строку ( TCHAR
является либо широким символом, либо символом, в зависимости от того, определен ли UNICODE в вашем проекте)
LPTSTR
указатель на (неконстантную) TCHAR
строку
На практике, когда мы говорили об этом в прошлом, для простоты мы не использовали фразу «указатель на», но, как упоминалось в lightness-races-in-orbit, все они являются указателями.
Это отличная статья по проекту кода, описывающая строки C ++ (см. 2/3 пути вниз для диаграммы, сравнивающей различные типы)
extern "C"
. Кроме того, да, ему определенно нужен либо бит "указатель", либо конкретное описание в виде строки C.
Быстро и грязно:
LP
== L Ong P ointer. Просто подумайте, указатель или символ *
C
= C onst, в этом случае, я думаю, они имеют в виду, что символьная строка является константой, а не указателем, являющимся константой.
STR
является строка
T
для широкого характера или полукокса (TCHAR) в зависимости от параметров компиляции.
char
: 8-битный символ - базовый тип данных C / C ++CHAR
: alias of char
- Тип данных WindowsLPSTR
: Завершается нулем строка CHAR
( L Ong P ointer)LPCSTR
: Константа завершается нулем строка CHAR
( L Ong P ointer)wchar_t
: 16-битный символ - базовый тип данных C / C ++WCHAR
: alias of 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-строки, а не LPCTSTR
. Что ты делаешь
1) преобразовать string
( CString
предположительно) в LPCTSTR
(что на практике означает получение адреса его символьного буфера как указателя только для чтения)
2) преобразовать этот доступный только для чтения указатель в записываемый указатель, отбросив его const
сущность.
Это зависит от того, dispinfo
для чего используется, есть ли вероятность, что ваш ListView
звонок в конечном итоге попытается написать через это pszText
. Если это так, то это потенциально очень плохо: в конце концов, вам дали указатель только для чтения, а затем вы решили рассматривать его как доступный для записи: возможно, есть причина, по которой он был доступен только для чтения!
Если это CString
то, с чем вы работаете, у вас есть возможность использовать string.GetBuffer()
- это намеренно дает вам возможность записи LPTSTR
. Затем вы должны не забыть позвонить, ReleaseBuffer()
если строка действительно изменилась. Или вы можете выделить локальный временный буфер и скопировать туда строку.
В 99% случаев в этом нет необходимости, и обращение с этим LPCTSTR
как LPTSTR
сработает ... но однажды, когда вы меньше всего этого ожидаете ...
xxx_cast<>()
вместо него.
xxx_cast<>
вместо смешивания двух разных стилей приведения на основе скобок!