c++ - lpcwstr - lpwstr to string




如何將std:: string轉換為LPCSTR? (6)

str.c_str()給你一個const char * ,它是一個LPCSTR (指向常量STRing的長指針) - 表示它是一個指向0終止的字符串的指針。 W表示寬字符串(由wchar_t組成,而不是char )。

我如何將std::string轉換為LPCSTR ? 另外,如何將std::string轉換為LPWSTR

我完全同這些LPCSTR LPSTR LPWSTRLPCWSTR混淆。

LPWSTRLPCWSTR是一樣的嗎?


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

查爾斯貝利給出的MultiByteToWideChar答案是正確的。 由於LPCWSTR只是const WCHAR*一個typedef,因此示例代碼中的LPWSTR可以用於任何需要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 )進入圖片。


調用c_str()std::string獲取一個const char *LPCSTR )。

這一切都是以這個名字命名的:

LPSTR - (長)指向字符串的指針 - char *

LPCSTR - (long)指向常量字符串的指針 - const char *

LPWSTR - (長)指向Unicode(寬)字符串的指針 - wchar_t *

LPCWSTR - (長)指向常量Unicode(寬)字符串的指針 - const wchar_t *

LPTSTR - (長)指向TCHAR的指針(如果UNICODE已定義則為Unicode,否則為ANSI)string - TCHAR *

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

您可以忽略名稱中的長(L)部分 - 這是16位Windows的延期。


轉換很簡單:

std::string myString;

LPCSTR lpMyString = myString.c_str();

需要注意的一點是,c_str不會返回myString的副本,而只是一個指向std :: string包裝的字符串的指針。 如果你想/需要一個副本,你需要使用strcpy自己創建一個。


這些是Microsoft定義的typedef,它們對應於:

LPCSTR:指向以char結尾的const結束字符串的指針

LPSTR:char的空字符串指針(通常是一個緩衝區被傳遞並用作'輸出'參數)

LPCWSTR:指向以常量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 。 如果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;
}




string