【问题标题】:LPSTR LPCTSTR explanationLPSTR LPCTSTR 解释
【发布时间】:2016-06-22 20:38:09
【问题描述】:

我有以下 c++ 代码:

#include "stdafx.h"
#include <atlstr.h>

int _tmain(int argc, _TCHAR* argv[])
{
    CString OFST_PATH;
    TCHAR DIR_PATH[MAX_PATH];

    GetCurrentDirectory(MAX_PATH, DIR_PATH);

    OFST_PATH.Format(DIR_PATH);

    CHAR *pOFST_PATH = (LPSTR)(LPCTSTR)OFST_PATH;

    return 0;
}

我想了解为什么程序末尾pOFST_PATH的值是“c”? (LPSTR)(LPCTSTR) 对变量 OFST_PATH 的强制转换对写入其中的整个路径做了什么?

正如您在以下窗口中看到的,调试变量时的值是:

【问题讨论】:

  • 你会帮自己一个忙,避免用所有这些微软特有的突变(如 LPCSTR 和 Cstring 等)污染你的大脑;而是坚持使用 C++ 标准类型,例如 char *std::string
  • 我完全同意你的观点,但我被限制只能使用它们:/
  • 这很不幸。过去,面对不可接受的工作环境,我通过换工作解决了问题。这种代码看得我眼花,怕长期脑损伤。

标签: c++ c-strings


【解决方案1】:

CStringLPCTSTR 都基于TCHAR,当UNICODE 被定义时是wchar_t(在你的情况下,我可以通过argv 的值来判断)你的调试器)。当你这样做时:

(LPCTSTR)OFST_PATH

这没问题,因为CString 有一个到LPCTSTR 的转换运算符。但是定义了UNICODELPCTSTR 就是LPCWSTR,也就是wchar_t const*。它指向一个 utf16 字符数组。该数组中的第一个字符是L'c'(这是'c' 的宽字符版本)。 L'c' 的字节在内存中如下所示:0x63 0x00。这是字母“c”的 ASCII 码,后跟一个零。因此,当您将 CString 转换为 LPCTSTR 时,这是有效的,但是,您的下一次转换:

(LPSTR)(LPCTSTR)OFST_PATH

这是无效的。 LPSTRchar*,因此您将 wchar_t const* 视为 char*。好吧,您的调试器假定当它看到char* 时,它正在查看以空字符结尾的窄字符串。如果你记得上面第一个字符的字节值是什么,它是字母“c”的 ASCII 值,后跟一个零。因此,调试器将其视为仅由字母“c”组成的以空字符结尾的字符串。

故事的寓意是,如果您不了解 c 风格的演员表的作用以及它们是否合适,请不要使用它们。

【讨论】:

  • 啊,我看不到图片。公平地说,他没有问为什么它的价值看起来很混乱。 :)
  • 更进一步,永远不要在 C++ 中使用 c 样式转换。如果您不了解 C++ 样式转换,尤其是在使用 reinterpret_cast&lt;&gt; 时,请不要使用它们。
猜你喜欢
  • 2017-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-11
  • 2012-04-04
相关资源
最近更新 更多