web-dev-qa-db-ja.com

std :: stringをLPCSTRに変換する方法は?

std::stringLPCSTRに変換するにはどうすればよいですか?また、どのようにしてstd::stringLPWSTRに変換できますか?

これらのLPCSTRLPSTRLPWSTRおよびLPCWSTRと完全に混同されています。

LPWSTRLPCWSTRは同じですか?

108
Cute

str.c_str()const char *を提供します。これはLPCSTR(定数STRingへのロングポインター)です。つまり、0で終わる文字列へのポインターです。 Wは、ワイド文字列(charの代わりにwchar_tで構成される)を意味します。

110
Lou Franco

c_str()を呼び出して、const char *からstd::stringLPCSTR)を取得します。

名前にすべてあります:

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からの持ち越しです。

147
Nick Meyer

これらは、Microsoftが定義したtypedefであり、以下に対応しています。

LPCSTR:charのnullで終わる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::stringLPWSTRに変換するのはより複雑です。 LPWSTRが必要なことは、変更可能なバッファが必要であることを意味し、文字エンコードstd::stringが使用しているものを理解する必要もあります。 std::stringにシステムのデフォルトエンコーディングを使用した文字列が含まれている場合(ここではウィンドウを想定)、必要なワイド文字バッファーの長さを確認し、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;
}
32
CB Bailey

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

チャールズベイリーがくれたMultiByteToWideCharの答えは正しいものです。 LPCWSTRconst WCHAR*の単なるtypedefであるため、サンプルコードのwidestrは、LPWSTRが予想される場所、またはLPCWSTRが予想される場所で使用できます。

1つの小さな調整は、手動で管理される配列の代わりに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を呼び出すだけです。 MultiByteToWideChar(およびその逆のWideCharToMultiByte)が現れるのは、ANSI文字とUTF-16文字の間を変更するときです。

4
Joel

変換は簡単です:

std::string myString;

LPCSTR lpMyString = myString.c_str();

ここで注意すべきことの1つは、c_strがmyStringのコピーを返さず、std :: stringがラップする文字列へのポインターのみを返すことです。コピーが必要な場合は、strcpyを使用して自分でコピーを作成する必要があります。

2
Nick Haddad

変換は簡単です:

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

1
Timbo

std::stringLPWSTRに変換する最も簡単な方法は、私の意見です:

  1. std::stringstd::vector<wchar_t>に変換します
  2. ベクター内の最初のwchar_tのアドレスを取得します。

std::vector<wchar_t>には、std::string.begin()および.end()イテレーターなどの2つのイテレーターを使用するテンプレート化されたctorがあります。ただし、これは各文字をwchar_tに変換します。 Unicode値がLatin-1値に似ているため、std::stringにASCIIまたはLatin-1が含まれる場合にのみ有効です。 CP1252または他のエンコーディングの文字が含まれている場合、より複雑です。次に、文字を変換する必要があります。

1
MSalters