LPCSTR, LPCTSTR и LPTSTR - PullRequest
       24

LPCSTR, LPCTSTR и LPTSTR

95 голосов
/ 26 ноября 2008

Какая разница между LPCSTR, LPCTSTR и LPTSTR?

Зачем нам это нужно для преобразования строки в структурную переменную LV / _ITEM pszText:

LV_DISPINFO dispinfo;  
dispinfo.item.pszText = LPTSTR((LPCTSTR)string);

Ответы [ 5 ]

109 голосов
/ 26 ноября 2008

Чтобы ответить на первую часть вашего вопроса:

LPCSTR является константной строкой

LPCTSTR - это строка const TCHAR (TCHAR - это широкий символ или символ в зависимости от того, определен ли в вашем проекте UNICODE)

LPTSTR является (неконстантной) TCHAR строкой

Это отличная статья codeproject , описывающая строки C ++ (см. 2/3, где приведена схема сравнения различных типов)

78 голосов
/ 26 ноября 2008

Быстро и грязно:

LP == L ong P ointer. Просто подумай, указатель или символ *

C = C Сначала, в этом случае, я думаю, они означают, что символьная строка является const, а не указатель, являющийся const.

STR - это строка

T для широкого символа или символа (TCHAR) в зависимости от параметров компиляции.

21 голосов
/ 28 сентября 2017

8-битные AnsiStrings

  • char: 8-битный символ - базовый тип данных C / C ++
  • CHAR: псевдоним char - тип данных Windows
  • LPSTR: строка с нулевым символом в конце CHAR ( L ong P ointer)
  • LPCSTR: постоянная строка с нулевым символом в конце CHAR ( L ong P ointer)

16-битные строки Unicode

  • wchar_t: 16-битный символ - базовый тип данных C / C ++
  • WCHAR: псевдоним wchar_t - тип данных Windows
  • LPWSTR: строка с нулевым символом в конце 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)

So

| Item              | 8-bit        | 16-bit      | Varies          |
|-------------------|--------------|-------------|-----------------|
| character         | CHAR         | WCHAR       | TCHAR           |
| string            | LPSTR        | LPWSTR      | LPTSTR          |
| string (const)    | LPCSTR       | LPCWSTR     | LPCTSTR         |

Бонус Чтение

TCHAR & rarr; Текстовый Char ( archive.is )

3 голосов
/ 06 сентября 2011

Чтобы ответить на вторую часть вашего вопроса, вам нужно сделать что-то вроде

LV_DISPINFO dispinfo;  
dispinfo.item.pszText = LPTSTR((LPCTSTR)string);

потому что структура MS LVITEM имеет LPTSTR, то есть изменяемый указатель на T-строку, а не LPCTSTR. То, что вы делаете, это

1) преобразовать string (a CString по предположению) в LPCTSTR (что на практике означает получение адреса его символьного буфера в виде указателя только для чтения)

2) преобразовать этот указатель только для чтения в записываемый указатель, отбрасывая его const -ness.

Это зависит от того, что dispinfo используется для того, есть ли вероятность того, что ваш ListView вызов закончится попыткой записи через этот pszText. Если это так, это потенциально очень плохая вещь: в конце концов вам дали указатель только для чтения, а затем решили рассматривать его как доступный для записи: возможно, есть причина, по которой он был доступен только для чтения!

Если это CString, с которым вы работаете, у вас есть возможность использовать string.GetBuffer() - который намеренно дает вам доступный для записи LPTSTR. Затем вы должны не забыть вызвать ReleaseBuffer(), если строка действительно изменилась. Или вы можете выделить локальный временный буфер и скопировать туда строку.

99% времени это будет ненужным, и трактовка LPCTSTR как LPTSTR будет работать ... но однажды, когда вы меньше всего этого ожидаете ...

3 голосов
/ 26 ноября 2008

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

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

  • LPWSTR
  • LPCWSTR

Остальные предназначены для поддержки платформ ANSI или двойной компиляции. Сегодня они не так актуальны, как раньше.

...