【问题标题】:How to convert std::string to LPCSTR?如何将 std::string 转换为 LPCSTR?
【发布时间】:2010-11-15 01:42:47
【问题描述】:

如何将std::string 转换为LPCSTR?另外,如何将std::string 转换为LPWSTR

我对这些 LPCSTR LPSTR LPWSTRLPCWSTR 完全感到困惑。

LPWSTRLPCWSTR 是否相同?

【问题讨论】:

    标签: c++ windows string


    【解决方案1】:

    str.c_str() 给你一个const char *,它是一个LPCSTR(指向常量字符串的长指针)——意味着它是一个指向0 终止字符串的指针。 W 表示宽字符串(由wchar_t 组成,而不是char)。

    【讨论】:

    • 次要的挑剔点:在 x64 上,LPCSTR 将是一个 64 位指针,指向一个(常量)以空字符结尾的字符串。
    【解决方案2】:

    转换很简单:

    std::string str; LPCSTR lpcstr = str.c_str();

    【讨论】:

      【解决方案3】:

      致电c_str() 以从std::string 获取const char * (LPCSTR)。

      一切尽在名下:

      LPSTR - 指向字符串的(长)指针 - char *

      LPCSTR - 指向常量字符串的(长)指针 - const char *

      LPWSTR - 指向 Unicode(宽)字符串的(长)指针 - wchar_t *

      LPCWSTR - 指向常量 Unicode(宽)字符串的(长)指针 - const wchar_t *

      LPTSTR - 指向 TCHAR 的(长)指针(如果定义了 UNICODE,则为 Unicode,否则为 ANSI)字符串 - TCHAR *

      LPCTSTR - 指向常量 TCHAR 字符串的(长)指针 - const TCHAR *

      您可以忽略名称的 L(长)部分——它是 16 位 Windows 的保留。

      【讨论】:

        【解决方案4】:

        这些是 Microsoft 定义的 typedef,对应于:

        LPCSTR:指向 char 的空终止 const 字符串的指针

        LPSTR:指向char 的空终止字符字符串的指针(通常传递一个缓冲区并用作“输出”参数)

        LPCWSTR:指向 const wchar_t 的空终止字符串的指针

        LPWSTR:指向以空结尾的wchar_t 字符串的指针(通常传递一个缓冲区并用作“输出”参数)

        std::string“转换”为LPCSTR 取决于具体的上下文,但通常调用.c_str() 就足够了。

        这行得通。

        void TakesString(LPCSTR param);
        
        void f(const std::string& param)
        {
            TakesString(param.c_str());
        }
        

        请注意,您不应该尝试做这样的事情。

        LPCSTR GetString()
        {
            std::string tmp("temporary");
            return tmp.c_str();
        }
        

        .c_str() 返回的缓冲区归std::string 实例所有,并且仅在字符串下次修改或销毁之前有效。

        std::string 转换为LPWSTR 更为复杂。想要一个LPWSTR 意味着您需要一个可修改的缓冲区,并且您还需要确保您了解std::string 使用的字符编码。如果std::string包含一个使用系统默认编码的字符串(假设windows,这里),那么您可以找到所需的宽字符缓冲区的长度并使用MultiByteToWideChar(Win32 API函数)执行转码。

        例如

        void f(const std:string& instr)
        {
            // Assumes std::string is encoded in the current Windows ANSI codepage
            int bufferlen = ::MultiByteToWideChar(CP_ACP, 0, instr.c_str(), instr.size(), NULL, 0);
        
            if (bufferlen == 0)
            {
                // Something went wrong. Perhaps, check GetLastError() and log.
                return;
            }
        
            // Allocate new LPWSTR - must deallocate it later
            LPWSTR widestr = new WCHAR[bufferlen + 1];
        
            ::MultiByteToWideChar(CP_ACP, 0, instr.c_str(), instr.size(), widestr, bufferlen);
        
            // Ensure wide string is null terminated
            widestr[bufferlen] = 0;
        
            // Do something with widestr
        
            delete[] widestr;
        }
        

        【讨论】:

          【解决方案5】:

          转换很简单:

          std::string myString;
          
          LPCSTR lpMyString = myString.c_str();
          

          这里要注意的一点是 c_str 不返回 myString 的副本,而只是一个指向 std::string 包装的字符串的指针。如果您想要/需要一份副本,您需要使用 strcpy 自己制作一份。

          【讨论】:

            【解决方案6】:

            我认为将std::string 转换为LPWSTR 的最简单方法是:

            1. std::string 转换为std::vector<wchar_t>
            2. 取向量中第一个wchar_t的地址。

            std::vector<wchar_t> 有一个模板化的 ctor,它将采用两个迭代器,例如 std::string.begin().end() 迭代器。不过,这会将每个字符转换为wchar_t。这仅在 std::string 包含 ASCII 或 Latin-1 时有效,因为 Unicode 值类似于 Latin-1 值。如果它包含 CP1252 或任何其他编码的字符,那就更复杂了。然后,您需要转换字符。

            【讨论】:

            • 为什么不使用std::wstring
            • @Timmmm:C++11 收紧了规范,因为实现没有利用旧规则,今天就可以了。
            【解决方案7】:

            使用LPWSTR 你可以改变它指向的字符串的内容。使用LPCWSTR 你不能改变它指向的字符串的内容。

            std::string s = SOME_STRING;
            // get temporary LPSTR (not really safe)
            LPSTR pst = &s[0];
            // get temporary LPCSTR (pretty safe)
            LPCSTR pcstr = s.c_str();
            // convert to std::wstring
            std::wstring ws; 
            ws.assign( s.begin(), s.end() );
            // get temporary LPWSTR (not really safe)
            LPWSTR pwst = &ws[0];
            // get temporary LPCWSTR (pretty safe)
            LPCWSTR pcwstr = ws.c_str();
            

            LPWSTR 只是指向原始字符串的指针。您不应该使用上面的示例从函数中返回它。要获得不是临时的LPWSTR,您应该在堆上复制原始字符串。检查以下示例:

            LPWSTR ConvertToLPWSTR( const std::string& s )
            {
              LPWSTR ws = new wchar_t[s.size()+1]; // +1 for zero at the end
              copy( s.begin(), s.end(), ws );
              ws[s.size()] = 0; // zero at the end
              return ws;
            }
            
            void f()
            {
              std::string s = SOME_STRING;
              LPWSTR ws = ConvertToLPWSTR( s );
            
              // some actions
            
              delete[] ws; // caller responsible for deletion
            }
            

            【讨论】:

              【解决方案8】:

              Charles Bailey 给出的MultiByteToWideChar 答案是正确的。因为LPCWSTR 只是const WCHAR* 的typedef,所以示例代码中的widestr 可以在任何需要LPWSTR 或需要LPCWSTR 的地方使用。

              一个小的调整是使用std::vector<WCHAR> 而不是手动管理的数组:

              // using vector, buffer is deallocated when function ends
              std::vector<WCHAR> widestr(bufferlen + 1);
              
              ::MultiByteToWideChar(CP_ACP, 0, instr.c_str(), instr.size(), &widestr[0], bufferlen);
              
              // Ensure wide string is null terminated
              widestr[bufferlen] = 0;
              
              // no need to delete; handled by vector
              

              另外,如果您需要从宽字符串开始,您可以使用std::wstring 而不是std::string。如果要使用 Windows TCHAR 类型,可以使用 std::basic_string&lt;TCHAR&gt;。从std::wstring 转换为LPCWSTR 或从std::basic_string&lt;TCHAR&gt; 转换为LPCTSTR 只需调用c_str。当您在 ANSI 和 UTF-16 字符之间切换时,MultiByteToWideChar(及其相反的WideCharToMultiByte)就会出现。

              【讨论】:

                【解决方案9】:
                std::string myString("SomeValue");
                LPSTR lpSTR = const_cast<char*>(myString.c_str());
                

                myString 是输入字符串,lpSTR 是它的 LPSTR 等效项。

                【讨论】:

                  猜你喜欢
                  • 2012-07-07
                  • 1970-01-01
                  • 2012-07-26
                  • 1970-01-01
                  • 2011-04-22
                  • 1970-01-01
                  • 2015-01-07
                  • 2016-01-28
                  相关资源
                  最近更新 更多