LPCSTR,LPCTSTR和LPTSTR

not*_*ter 101 c++ windows mfc visual-c++

什么区别LPCSTR,LPCTSTRLPTSTR

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

LV_DISPINFO dispinfo;  
dispinfo.item.pszText = LPTSTR((LPCTSTR)string);
Run Code Online (Sandbox Code Playgroud)

Joh*_*bly 113

回答你问题的第一部分:

LPCSTR 是一个const字符串

LPCTSTR是一个const TCHAR字符串,(TCHAR根据是否在项目中定义了UNICODE,可以是宽字符或char)

LPTSTR是(非const)TCHAR字符串

这是一篇很棒的代码项目文章,描述了C++字符串(参见2/3,比较不同类型的图表的方式)

  • 一切都错了.这些东西都不是字符串.他们都是指针.-1 (14认同)
  • @LightnessRacesinOrbit你在技术上是正确的 - 尽管根据我的经验,在C++中引用字符串类型时,通常的做法是省略"指向...的指针"以简洁起见 (6认同)
  • 请注意,该代码项目文章是在15年前编写的,除非它得到更新,否则包含有关Unicode字符总是2个字节的误导性假设.那是完全错误的.甚至UTF16也是可变长度的...更好的说宽字符是UCS-2编码的,并且在此上下文中的"Unicode"指的是UCS-2. (3认同)
  • @JohnSily:在 C 中,是的。在 C++ 中,绝对不应该!! (2认同)

Tim*_*Tim 83

又快又脏:

LP== L ong P ointer.想想指针或字符*

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

STR字符串

T是用于根据编译选项宽字符或字符(TCHAR).

  • T不适用于宽字符,它适用于不同的字符类型.W代表宽(如WCHAR).如果定义了UNICODE,则TCHAR == WCHAR,否则TCHAR == CHAR.因此,如果未定义UNICODE,则LPCTSTR == LPCSTR. (15认同)
  • 我真的很喜欢这种解释:).非常感谢 (14认同)
  • 这就是为什么我写"取决于编译选项" (9认同)
  • [** T **表示** T ** ext](https://blogs.msdn.microsoft.com/oldnewthing/20061017-03/?p=29363) (2认同)

Ian*_*oyd 27

8位AnsiStrings

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

16位UnicodeStrings

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

取决于UNICODE定义

  • TCHAR:WCHAR如果定义了UNICODE的别名; 除此以外CHAR
  • LPTSTR:以null结尾的字符串TCHAR (L ong P ointer)
  • LPCTSTR:常量以null结尾的字符串TCHAR (L ong P ointer)

所以

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

奖金阅读

TCHAR文字字符 (archive.is)

  • 遗憾的是,这个答案永远不会成为顶级,因为它是如此新颖......这真的是SO需要解决的问题.到目前为止,这是最好的答案. (3认同)
  • 很好的答案。我认为值得补充的是,unicode 版本使用 UTF16,因此每个 16 位块不是一个字符,而是一个代码单元。这些名称是历史性的(当 Unicode === UCS2 时)。 (3认同)

Jar*_*Par 6

添加到约翰和蒂姆的答案。

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

  • LPWSTR
  • LPCWSTR

其余的旨在支持 ANSI 平台或双重编译。这些在今天不像过去那样重要。

  • @BlueRaja,我在回答中主要指的是基于 C 的字符串。但是对于 C++,我会避免使用 `std::string`,因为它仍然是基于 ASCII 的字符串,而更喜欢使用 `std::wstring`。 (2认同)

AAT*_*AAT 5

要回答问题的第二部分,您需要执行以下操作

LV_DISPINFO dispinfo;  
dispinfo.item.pszText = LPTSTR((LPCTSTR)string);
Run Code Online (Sandbox Code Playgroud)

因为 MS 的LVITEMstruct 有一个LPTSTR,即可T 字符串指针,而不是LPCTSTR. 你正在做的是

1)将stringCString猜测的a)转换为an LPCTSTR(这实际上意味着将其字符缓冲区的地址作为只读指针获取)

2) 通过放弃其 -ness 将该只读指针转换为可写指针const

这取决于dispinfo您的调用最终是否有机会ListView尝试写入内容,这取决于所使用的内容pszText。如果确实如此,这可能是一件非常糟糕的事情:毕竟您获得了一个只读指针,然后决定将其视为可写:也许它是只读的是有原因的!

如果它是CString你正在使用的,你可以选择使用string.GetBuffer()- 这故意给你一个可写的LPTSTRReleaseBuffer()然后,如果字符串确实发生更改,您必须记住调用。或者您可以分配一个本地临时缓冲区并将字符串复制到其中。

99% 的情况下,这是不必要的,将其视为LPCTSTR可行LPTSTR......但有一天,当你最意想不到的时候......