В чем разница между 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
LPCTSTR
является строкой const TCHAR
, (TCHAR
является либо широким char, либо char в зависимости от того, определен ли UNICODE в вашем проекте)
LPTSTR
- строка (не const) TCHAR
Это отличная статья статьи кодекса, описывающая строки С++ (см. 2/3 путь вниз для диаграммы, сравнивающей разные типы)
Быстро и грязно:
LP
== L ong P ointer. Просто подумайте, указатель или символ *
C
= C, в данном случае, я думаю, они означают, что символьная строка является const, а не указателем, являющимся const.
STR
это строка
T
для широкого символа или символа (TCHAR) в зависимости от параметров компиляции.
char
: 8-битный символ - базовый тип данных C/C++CHAR
: псевдоним char
- тип данных WindowsLPSTR
: строка CHAR
нулевым символом в CHAR
(L ong P ointer)LPCSTR
: постоянная строка CHAR
нулевым символом в CHAR
(L ong P ointer)wchar_t
: 16-битный символ - базовый тип данных C/C++WCHAR
: псевдоним wchar_t
- тип данных WindowsLPWSTR
: строка LPWSTR
нулевым символом в WCHAR
(L ong P ointer)LPCWSTR
: постоянная строка WCHAR
нулевым символом в WCHAR
(L ong P ointer)UNICODE
определитьTCHAR
: псевдоним WCHAR
если определен UNICODE; в противном случае CHAR
LPTSTR
: строка LPTSTR
нулевым символом в TCHAR
(L ong P ointer)LPCTSTR
: константная строка с TCHAR
символом в 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
→ Text Char (archive.is)
Добавление к Джону и Тиму ответа.
Если вы не кодируете Win98, в вашем приложении должны быть только два из шести типов строк
LPWSTR
LPCWSTR
Остальные предназначены для поддержки платформ ANSI или двойных компиляций. Сегодня они не так актуальны, как раньше.
Чтобы ответить на вторую часть вашего вопроса, вам нужно сделать что-то вроде
LV_DISPINFO dispinfo;
dispinfo.item.pszText = LPTSTR((LPCTSTR)string);
поскольку MS LVITEM
struct имеет LPTSTR
, т.е. изменяемый указатель T-строки, а не LPCTSTR
. Что вы делаете, это
1) преобразуйте string
(a CString
при угадывании) в LPCTSTR
(что на практике означает получение адреса его символьного буфера в качестве указателя только для чтения)
2) конвертируйте этот указатель только на чтение в записываемый указатель, отбросив его const
-ness.
Это зависит от того, что используется dispinfo
для того, есть ли вероятность того, что ваш вызов ListView
завершится попыткой написать через pszText
. Если это так, это очень опасно: в конце концов вы получили указатель только для чтения, а затем решили рассматривать его как записываемый: возможно, есть причина, по которой он был доступен только для чтения!
Если это CString
, с которым вы работаете, у вас есть возможность использовать string.GetBuffer()
- это намеренно дает вам возможность записи LPTSTR
. Затем вам нужно запомнить вызов ReleaseBuffer()
, если строка будет изменена. Или вы можете выделить локальный временный буфер и скопировать туда строку.
В 99% случаев это будет лишним, и обработка LPCTSTR
как LPTSTR
будет работать... но однажды, когда вы меньше всего этого ожидаете...