LPCSTR,LPCTSTR和LPTSTR

时间:2008-11-26 17:01:16

标签: c++ windows visual-c++ mfc

LPCSTRLPCTSTRLPTSTR之间的区别是什么?

为什么我们需要这样做才能将字符串转换为LV / _ITEM结构变量pszText

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

6 个答案:

答案 0 :(得分:108)

回答问题的第一部分:

LPCSTR是一个常量字符串

LPCTSTRconst TCHAR字符串,(TCHAR是宽字符或字符,具体取决于项目中是否定义了UNICODE)

LPTSTR是一个(非常量)TCHAR字符串

这是一个很好的codeproject article描述C ++字符串(比较不同类型的图表,请参阅2/3)

答案 1 :(得分:78)

又快又脏:

LP == L ong P ointer。想想指针或char *

C = C onst,在这种情况下,我认为它们意味着字符串是const,而不是指针是const。

STR字符串

T用于宽字符或字符(TCHAR),具体取决于编译选项。

答案 2 :(得分:21)

8位AnsiStrings

  • char:8位字符 - 基础C / C ++数据类型
  • CHARchar的别名 - Windows数据类型
  • LPSTR:以空字母结尾的CHAR 字符串( L ong P ointer)
  • LPCSTRCHAR 的常量以空字符结尾的字符串( L ong P ointer)

16位UnicodeStrings

  • wchar_t:16位字符 - 基础C / C ++数据类型
  • WCHARwchar_t的别名 - Windows数据类型
  • LPWSTR:以空字母结尾的WCHAR 字符串( L ong P ointer)
  • LPCWSTRWCHAR 的常量以空字符结尾的字符串( L ong P ointer)

取决于UNICODE define

  • TCHAR:如果定义了UNICODE,则为WCHAR的别名;否则CHAR
  • LPTSTR:以空字母结尾的TCHAR 字符串( L ong P ointer)
  • LPCTSTRTCHAR 的常量以空字符结尾的字符串( 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

答案 3 :(得分:3)

添加John和Tim的回答。

除非您为Win98编写代码,否则您应用程序中应使用的6种以上字符串类型中只有两种

  • LPWSTR
  • LPCWSTR

其余的旨在支持ANSI平台或双重编译。那些在今天并不像以前那么重要。

答案 4 :(得分:3)

要回答问题的第二部分,您需要执行

之类的操作
LV_DISPINFO dispinfo;  
dispinfo.item.pszText = LPTSTR((LPCTSTR)string);

因为MS的LVITEM结构具有LPTSTR,即可变 T字符串指针,而不是LPCTSTR。你在做什么

1)将string(猜测时为CString)转换为LPCTSTR(实际上意味着将其字符缓冲区的地址作为只读指针)

2)通过丢弃它的const来将该只读指针转换为可写指针。

这取决于dispinfo是否有ListView次调用最终可能通过pszText尝试。如果确实如此,这可能是一件非常糟糕的事情:毕竟你被赋予了一个只读指针,然后决定将其视为可写:也许有一个原因是它是只读的!

如果您与CString合作,则可以选择使用string.GetBuffer() - 故意为您提供可写LPTSTR。然后,如果字符串确实被更改,则必须记住调用ReleaseBuffer()。或者您可以分配一个本地临时缓冲区并将字符串复制到那里。

99%的时间这是不必要的,将LPCTSTR视为LPTSTR会有效......但有一天,当你最不期望它时......

答案 5 :(得分:0)

该问题第二部分的简短答案很简单,就是CString类没有按设计提供直接的类型转换,而您所做的只是作弊。

以下是更长的答案:

之所以可以将CString转换为LPCTSTR的原因是因为CString通过覆盖operator=来提供此功能。根据设计,它仅可转换为LPCTSTR指针,因此无法使用此指针修改字符串值。

换句话说,出于与上述相同的原因,它根本没有提供将operator=转换为CString的重载LPSTR。他们不想允许以这种方式更改字符串值。

因此,本质上,诀窍是使用运算符CString提供并获得此信息:

LPTSTR lptstr = (LPCTSTR) string; // CString provide this operator overload

现在LPTSTR可以进一步转换为LPSTR了:)

dispinfo.item.pszText = LPTSTR( lpfzfd); // accomplish the cheat :P

从“ CString”获取LPTSTR的正确方法是(完整示例):

CString str = _T("Hello");
LPTSTR lpstr = str.GetBuffer(str.GetAllocLength());
str.ReleaseBuffer(); // you must call this function if you change the string above with the pointer

再次,因为GetBuffer()返回LPTSTR的原因,现在您可以进行修改了:)