【问题标题】:wstringstream to LPWSTRwstringstream 到 LPWSTR
【发布时间】:2011-11-08 01:05:27
【问题描述】:

我使用wstringstream 构建了一个字符串,需要将它分配给LPWSTR 类型的struct 的成员。我尝试使用my_stringstream.str().c_str(),但得到以下编译时错误:

无法从 'const wchar_t *' 转换为 'LPWSTR'

我该怎么做?当我尝试在 GUI 中显示字符串时,我尝试了许多不同的转换组合,这些转换具有更多的编译时错误或随机术语。

【问题讨论】:

  • LPWSTRwchar_t* 的类型定义,我相信,所以你需要一个指向非常量的指针。将您的字符串复制到可变内存区域。或者仔细检查你的消费者函数为什么它需要一个可变字符串,也许这是一个错误。
  • 顺便问一下,struct 你要填什么?

标签: c++ wchar-t string-conversion


【解决方案1】:

LPWSTRtypedefd 为 wchar_t*。您正在尝试将 const wchar_t* 转换为 wchar_t*。你不能隐含地这样做。

您可以使用const_cast 解决此问题,但前提是您确定该函数不会修改内存:

wstring str = my_stringstream.str();
LPWSTR str = const_cast<LPWSTR>(str.c_str());

请注意,您不想这样做const_cast&lt;LPWSTR&gt;(my_stringstream.str().c_str())(除非您将其传递给函数),因为这将创建一个临时字符串对象,获取它的指针,将其转换为@987654330 @ 然后你从 str() 得到的临时字符串将在该行的末尾被销毁,让你的 LPWSTR 指向一个已释放的内存块。

如果您将LPWSTR 传递给的函数正在修改字符串,请参阅Kerrek's answer

【讨论】:

    【解决方案2】:

    原因很简单:LPWSTR 扩展为 wchar_t *。由于指向流内容的指针是一个const,因此不可能将这个const 抛开,除非使用const_cast&lt;LPWSTR&gt;(my_stringstream.str().c_str())。但是我建议不要这样做(因为您可能会简单地搞砸和/或以这种方式修改一些不同的东西。只有在您确定它不会被修改或修改无关紧要时才这样做。

    最简单(也是最安全的解决方案)是在缓冲区中创建您自己的由wstringstream 提供的字符串的副本,并在结构中引用这个副本。只是不要忘记稍后释放内存。

    【讨论】:

      【解决方案3】:

      如果您绝对确定字符串的内容不会被修改,您可以通过static_castconst 强制转换掉;可以接受的情况是,例如,如果您使用一些 struct 向函数提供数据,但同样的 struct 也用于检索它,因此该成员是 LPWSTR 而不仅仅是 @ 987654326@.

      相反,如果您将传递struct 的函数需要修改字符串,您有两种选择。

      最安全的方法是将字符串的单独副本分配为WCHAR 的原始动态数组,并在那里复制wstring 的内容。您可能希望用智能指针包装 new 的结果,除非您要转移字符串的所有权(在这种情况下,您可能必须使用一些特殊的分配函数)。

      您还可以使用&amp;YourString[0] 将指针传递给字符串的内部缓冲区,但是(1)我不确定它是否能保证按标准工作,并且(2)只有当函数获胜时它才能正常工作'不要改变你的字符串的长度,在它的结尾添加一个L'\0';在这种情况下,您还应该重新调整字符串的实际长度。

      无论是在最后一种情况下还是在第一种情况下,您都必须确保您传递 struct 的函数不要期望指向缓冲区的寿命长于您的 wstring 的范围(小心:@987654335 @ 是一个临时的,在你使用它的那一行就会死掉,你必须将它分配给一个新变量以赋予它更广泛的范围)。

      【讨论】:

        【解决方案4】:

        您的函数需要一个指向可修改数据的指针,即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]
        

        【讨论】:

        • 另一方面,这不考虑crazy_functionbuf.end() 之前将L'\0' 写成的字符串缩短的情况。我认为最好使用通常的 C 字符串构造函数 (std::wstring newstr(&amp;buf[0])) 简单地重建 newstr
        【解决方案5】:
        std::wstring temp(my_stringstream.str());
        lpwstrVar = &temp[0];
        

        【讨论】:

          【解决方案6】:
            wstringstream b;
              ..
              wchar_t z[100];
              b.read(z,100);
          

          已知字符串长度小于 101。 它可以在没有unsetf(std::ios_base::skipws) 和所有这些的情况下工作。并且在 wchar_t 数组上没有 ZeroMemory

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-06-08
            • 2014-03-06
            • 1970-01-01
            • 2013-05-13
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-01-23
            相关资源
            最近更新 更多