我使用wstringstream
构建了一个字符串,需要将其分配给struct
类型LPWSTR
的成员。我尝试使用my_stringstream.str().c_str()
,但得到以下编译时错误:
无法从'const wchar_t *'转换为'LPWSTR'
我该怎么做?当我尝试在GUI中显示字符串时,我尝试了许多不同的强制转换组合,其中包含更多编译时错误或随机行话。
答案 0 :(得分:7)
您的函数需要一个指向可修改数据的指针,即wchar_t*
,但标准字符串类只暴露指向常量的指针。假设你的函数实际上可能写入内存,我们需要为它提供一个有效的指针。
获取可修改缓冲区的简便方法是vector
:
std::vector<wchar_t> buf(mystring.begin(), mystring.end());
buf.push_back(0); // because your consumer expects null-termination
crazy_function(buf.data());
crazy_function(&buf[0]); // old-style
// need a string again?
std::wstring newstr(buf.data()); // or &buf[0]
答案 1 :(得分:5)
LPWSTR
typedef
为wchar_t*
。您正在尝试将const wchar_t*
转换为wchar_t*
。你不能暗中这样做。
您可以使用const_cast
解决此问题,但前提是您确定该功能不会修改内存:
wstring str = my_stringstream.str();
LPWSTR str = const_cast<LPWSTR>(str.c_str());
请注意,您不想 const_cast<LPWSTR>(my_stringstream.str().c_str())
(除非您将其传递给函数),因为这将创建一个临时字符串对象,获取它的指针,将其转换为LPWSTR
然后从str()
获取的临时字符串将在该行的末尾被销毁,让LPWSTR
指向一个已释放的内存块。
如果您将LPWSTR
传递给的功能修改字符串,请参阅Kerrek's answer。
答案 2 :(得分:1)
wstringstream b;
..
wchar_t z[100];
b.read(z,100);
其中已知字符串长度小于101。
它没有unsetf(std::ios_base::skipws)
和所有这一切。并且在wchar_t数组上没有ZeroMemory
。
答案 3 :(得分:0)
原因很简单:LPWSTR
扩展为wchar_t *
。由于指向流内容的指针是const
,因此除非使用const
,否则无法将此const_cast<LPWSTR>(my_stringstream.str().c_str())
转换为wstringstream
。但是我建议不要这样做(因为你可能只是搞砸了这个和/或修改不同的东西。只有你确定它不会被修改或修改无关紧要。
最简单(也是最安全的解决方案)是在缓冲区中创建自己的{{1}}提供的字符串副本,并在结构中引用它。只是不要忘记以后释放内存。
答案 4 :(得分:0)
如果您完全确定不会修改字符串的内容,可以通过const
投射static_cast
;例如,如果您使用某些struct
向函数提供数据,但是同样的struct
也用于检索它,那么该成员就是{{1}而不仅仅是LPWSTR
。
相反,如果您要传递LPCWSTR
的函数需要修改字符串,则有两种选择。
最安全的方法是将字符串的单独副本分配为struct
的原始动态数组,并在其中复制WCHAR
的内容。您可能希望用智能指针包装wstring
的结果,除非您转移字符串的所有权(在这种情况下,您可能必须使用一些特殊的分配函数)。
您也可以使用new
将指针传递给字符串的内部缓冲区,但是(1)我不确定它是否符合标准,并且(2)只有在函数不会改变字符串的长度,在它结束之前添加&YourString[0]
;在这种情况下,您还应该重新调整字符串的实际长度。
在最后一个和第一个案例中,您必须确保您传递L'\0'
的函数不希望指向的缓冲区的活动时间超过struct
的范围(小心:wstring
是一个临时的,它会在你使用它的行上消失,你必须将它分配给一个新的变量以赋予它更宽的范围。)
答案 5 :(得分:0)
std::wstring temp(my_stringstream.str());
lpwstrVar = &temp[0];