如何将std :: string转换为LPCSTR?

时间:2009-07-29 13:18:16

标签: c++ windows string

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

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

LPWSTRLPCWSTR是否相同?

9 个答案:

答案 0 :(得分:145)

致电c_str()const char *获取LPCSTRstd::string)。

这一切都在名称中:

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

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

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

的指针

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

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

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

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

答案 1 :(得分:107)

str.c_str()为您提供const char *,这是LPCSTR(指向常量字符串的长指针) - 表示它是指向0已终止字符串的指针。 W表示宽字符串(由wchar_t而非char组成)。

答案 2 :(得分:32)

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

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

的指针

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

LPCWSTR:指向以null结尾的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函数)执行转码

e.g。

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;
}

答案 3 :(得分:17)

使用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
}

答案 4 :(得分:4)

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<TCHAR>。从std::wstring转换为LPCWSTR或从std::basic_string<TCHAR>转换为LPCTSTR只需要调用c_str。当您在ANSI和UTF-16字符之间进行切换时,MultiByteToWideChar(及其反WideCharToMultiByte)会出现在图片中。

答案 5 :(得分:2)

转换很简单:

std::string myString;

LPCSTR lpMyString = myString.c_str();

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

答案 6 :(得分:1)

转换很简单:

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

答案 7 :(得分:1)

在我看来,将std::string转换为LPWSTR的最简单方法是:

  1. std::string转换为std::vector<wchar_t>
  2. 获取向量中第一个wchar_t的地址。
  3. std::vector<wchar_t>有一个模板化的ctor,需要两个迭代器,例如std::string.begin().end()迭代器。但是,这会将每个char转换为wchar_t。这仅在std::string包含ASCII或Latin-1时有效,因为Unicode值类似于Latin-1值。如果它包含CP1252或任何其他编码的字符,则更复杂。然后,您需要转换字符。

答案 8 :(得分:0)

std::string myString("SomeValue");
LPSTR lpSTR = const_cast<char*>(myString.c_str());

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