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         |

Бонус Чтение

TCHARText Char (archive.is)

Ответ 4

Добавление к Джону и Тиму ответа.

Если вы не кодируете Win98, в вашем приложении должны быть только два из шести типов строк

  • LPWSTR
  • LPCWSTR

Остальные предназначены для поддержки платформ 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 будет работать... но однажды, когда вы меньше всего этого ожидаете...