LPCSTR, LPCTSTR и LPTSTR
В чем разница между LPCSTR
, LPCTSTR
и LPTSTR
?
Зачем нам это нужно, чтобы преобразовать строку в структурную переменную LV
/_ITEM
pszText
:
LV_DISPINFO dispinfo;
dispinfo.item.pszText = LPTSTR((LPCTSTR)string);
Ответы
Ответ 1
Чтобы ответить на первую часть вашего вопроса:
LPCSTR
является строкой const
LPCTSTR
является строкой const TCHAR
, (TCHAR
является либо широким char, либо char в зависимости от того, определен ли UNICODE в вашем проекте)
LPTSTR
- строка (не const) TCHAR
Это отличная статья статьи кодекса, описывающая строки С++ (см. 2/3 путь вниз для диаграммы, сравнивающей разные типы)
Ответ 2
Быстро и грязно:
LP
== L ong P ointer. Просто подумайте, указатель или символ *
C
= C, в данном случае, я думаю, они означают, что символьная строка является const, а не указателем, являющимся const.
STR
это строка
T
для широкого символа или символа (TCHAR) в зависимости от параметров компиляции.
Ответ 3
8-битные AnsiStrings
-
char
: 8-битный символ - базовый тип данных C/C++ -
CHAR
: псевдоним char
- тип данных Windows -
LPSTR
: строка CHAR
нулевым символом в CHAR
(L ong P ointer) -
LPCSTR
: постоянная строка CHAR
нулевым символом в CHAR
(L ong P ointer)
16-битные UnicodeStrings
-
wchar_t
: 16-битный символ - базовый тип данных C/C++ -
WCHAR
: псевдоним wchar_t
- тип данных Windows -
LPWSTR
: строка 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)
Ответ 4
Добавление к Джону и Тиму ответа.
Если вы не кодируете Win98, в вашем приложении должны быть только два из шести типов строк
Остальные предназначены для поддержки платформ ANSI или двойных компиляций. Сегодня они не так актуальны, как раньше.
Ответ 5
Чтобы ответить на вторую часть вашего вопроса, вам нужно сделать что-то вроде
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
будет работать... но однажды, когда вы меньше всего этого ожидаете...