Вопрос:
В чем разница между 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 путь вниз для диаграммы, сравнивающей разные типы)
Ответ №1
Быстро и грязно:
LP == L ong P ointer. Просто подумайте, указатель или символ *
C= C, в данном случае, я думаю, они означают, что символьная строка является const, а не указателем, являющимся const.
STR это строка
T для широкого символа или символа (TCHAR) в зависимости от параметров компиляции.
Ответ №2Содержание
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)
Ответ №3
Добавление к Джону и Тиму ответа.
Если вы не кодируете Win98, в вашем приложении должны быть только два из шести типов строк
- LPWSTR
- LPCWSTR
Остальные предназначены для поддержки платформ ANSI или двойных компиляций. Сегодня они не так актуальны, как раньше.
Ответ №4
Чтобы ответить на вторую часть вашего вопроса, вам нужно сделать что-то вроде
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 будет работать… но однажды, когда вы меньше всего этого ожидаете…