C ++需要解释`static const WCHAR *`

时间:2013-12-23 14:37:25

标签: c++

制作Direct2D程序,我想从int转换为WCHAR,所以我编写了以下代码

void DemoApp::OnRender() {

//...

int a = 256;
std::wstring wStr = std::to_wstring(a);
static const WCHAR* pStrNum = wStr.c_str();

//Print the number to the screen
_pRenderTarget->DrawText(
     pStrNum,
     sizeof(pStrNum)/sizeof(pStrNum[0]),
     _pTextFormat,
     rect,
     _pBrush);
//...
};

然而,在一个循环之后,pStrNum变为奇怪的东西,起始字符是5028十进制基数。

稍微弄乱后,我将转换代码更改为

const WCHAR* pStrNum = wStr.c_str();

字符串几乎正确地打印在屏幕上,除了sizeof(pStrNum)/sizeof(pStrNum[0])的值为2之外,一切似乎都正常,因此只打印屏幕上的前两个字符。毕竟,我必须使用{ {1}}获取该字符串中的元素数。

我需要解释为什么lstrlenW()static const WCHAR*不同并导致错误

为什么const WCHAR*在这种情况下不起作用?

4 个答案:

答案 0 :(得分:1)

sizeof(pStrNum)为您提供WCHAR*的大小,而不是它指向的字符串。

当您有权访问数组声明时,只能使用sizeof(arr)/sizeof(arr[0])计算数组的长度。在其他时候,您需要传递一个大小和数组或迭代它的元素,直到找到标记元素结尾的sentinel元素。对于C风格的字符串,您可以迭代其元素,直到找到值为\0的元素。 wcslenwchar_t执行此操作。

_pRenderTarget->DrawText(
     pStrNum,
     wcslen(pStrNum),
     _pTextFormat,
     rect,
     _pBrush);

或者更简单,正如Kerrek SB建议的那样,删除所有pStrNum

的使用
_pRenderTarget->DrawText(
     wStr.data(),
     wStr.size(),
     _pTextFormat,
     rect,
     _pBrush);

答案 1 :(得分:1)

我认为(而且我肯定知道如果我得到很多downvotes)你的代码的行为是 undefined

这是因为

static const WCHAR* pStrNum = wStr.c_str();

static存储将初始化一次。

但是每次调用函数时都会初始化wStr,这就是问题:在对函数的所有后续调用中,指针将悬空并且行为未定义。

如果我是你,我会及时评估上的.c_str()。这样做不会有性能开销。

回答你的问题:使用wStr.size()来获取字符串的长度:sizeof()返回数据类型的大小(在编译时计算),而不是字符串长度。

答案 2 :(得分:0)

sizeof为您提供传递它的对象表示的大小。您将pStrNum提供给sizeof,而pStrNumconst WCHAR*,因此您获得的是指针的大小。 sizeof无法确定字符串的长度。

答案 3 :(得分:0)

您的代码不起作用的原因是编译器使用变量的静态类型来评估sizeofsizeof(pStrNum)将是4或8个字节,具体取决于您的操作系统,因为变量是一个指针。

只需将代码重写为:

_pRenderTarget->DrawText(
     wStr.c_str(),
     wStr.length(),
     _pTextFormat,
     rect,
     _pBrush);

你会没事的