Wie konvertiere ich std :: string in LPCSTR?

111

Wie kann ich ein std::stringin konvertieren LPCSTR? Wie kann ich ein std::stringin konvertieren LPWSTR?

Ich bin total verwirrt mit diesen LPCSTR LPSTR LPWSTRund LPCWSTR.

Sind LPWSTRund LPCWSTRdas gleiche?

Niedlich
quelle

Antworten:

114

str.c_str()gibt Ihnen ein const char *, was ein LPCSTR(langer Zeiger auf konstante STRing) ist - bedeutet, dass es ein Zeiger auf eine 0abgeschlossene Zeichenfolge ist. Wbedeutet breite Zeichenfolge (zusammengesetzt aus wchar_tstatt char).

Lou Franco
quelle
5
Kleiner wählerischer Punkt: Auf x64 wäre LPCSTR ein 64-Bit-Zeiger auf eine (konstante) nullterminierte Zeichenfolge.
Joel
153

Rufen Sie c_str()an, um ein const char *( LPCSTR) von a zu erhalten std::string.

Es ist alles im Namen:

LPSTR - (langer) Zeiger auf String - char *

LPCSTR - (langer) Zeiger auf konstante Zeichenfolge - const char *

LPWSTR - (langer) Zeiger auf Unicode (breite) Zeichenfolge - wchar_t *

LPCWSTR - (langer) Zeiger auf konstante Unicode (breite) Zeichenfolge - const wchar_t *

LPTSTR - (langer) Zeiger auf TCHAR-Zeichenfolge (Unicode, wenn UNICODE definiert ist, ANSI, wenn nicht) - TCHAR *

LPCTSTR - (langer) Zeiger auf konstante TCHAR-Zeichenfolge - const TCHAR *

Sie können den L-Teil (lange) der Namen ignorieren - dies ist ein Überbleibsel von 16-Bit-Windows.

Nick Meyer
quelle
32

Dies sind von Microsoft definierte Typedefs, die entsprechen:

LPCSTR: Zeiger auf nullterminierte const-Zeichenfolge von char

LPSTR: Zeiger auf nullterminierte Zeichenfolge von char(häufig wird ein Puffer übergeben und als 'Ausgabe'-Parameter verwendet)

LPCWSTR: Zeiger auf eine nullterminierte Zeichenfolge von const wchar_t

LPWSTR: Zeiger auf eine nullterminierte Zeichenfolge von wchar_t(häufig wird ein Puffer übergeben und als 'Ausgabe'-Parameter verwendet)

Das "Konvertieren" von a std::stringin einen LPCSTR hängt vom genauen Kontext ab, aber normalerweise ist ein Aufruf .c_str()ausreichend.

Das funktioniert.

void TakesString(LPCSTR param);

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

Beachten Sie, dass Sie nicht versuchen sollten, so etwas zu tun.

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

Der von zurückgegebene Puffer .c_str()gehört der std::stringInstanz und ist nur gültig, bis die Zeichenfolge das nächste Mal geändert oder zerstört wird.

So konvertiert ein std::stringzu einem LPWSTRkomplizierter ist. Wenn LPWSTRSie einen wünschen, müssen Sie einen modifizierbaren Puffer benötigen und sicher sein, dass Sie verstehen, welches Zeichen für die Codierung verwendetstd::string wird. Wenn der std::stringeine Zeichenfolge mit der Standardcodierung des Systems enthält (hier unter der Annahme von Fenstern), können Sie die Länge des erforderlichen breiten Zeichenpuffers ermitteln und die Transcodierung mit MultiByteToWideChar(einer Win32-API-Funktion) durchführen.

z.B

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;
}
CB Bailey
quelle
18

Mit können LPWSTRSie den Inhalt der Zeichenfolge dort ändern, wo sie zeigt. Mit können LPCWSTRSie den Inhalt der Zeichenfolge nicht ändern, auf die sie verweist.

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();

LPWSTRist nur ein Zeiger auf die ursprüngliche Zeichenfolge. Sie sollten es nicht mit dem obigen Beispiel von der Funktion zurückgeben. Um nicht vorübergehend zu werden LPWSTR, sollten Sie eine Kopie der Originalzeichenfolge auf dem Heap erstellen. Überprüfen Sie das folgende Beispiel:

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
}
Kirill V. Lyadvinsky
quelle
4

Die MultiByteToWideCharAntwort, die Charles Bailey gab, ist die richtige. Da LPCWSTRes sich nur um ein typedef für handelt const WCHAR*, kann widestrim Beispielcode überall dort verwendet werden, wo a LPWSTRerwartet wird oder wo a LPCWSTRerwartet wird.

Eine kleine Änderung wäre die Verwendung std::vector<WCHAR>anstelle eines manuell verwalteten Arrays:

// 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

Wenn Sie zunächst mit breiten Zeichenfolgen arbeiten müssen, können Sie std::wstringstattdessen anstelle von verwenden std::string. Wenn Sie mit dem Windows- TCHARTyp arbeiten möchten , können Sie verwenden std::basic_string<TCHAR>. Das Konvertieren von std::wstringnach LPCWSTRoder von std::basic_string<TCHAR>nach LPCTSTRist nur eine Frage des Anrufs c_str. Wenn Sie zwischen ANSI- und UTF-16-Zeichen wechseln, wird das Bild MultiByteToWideChar(und seine Umkehrung WideCharToMultiByte) angezeigt.

Joel
quelle
3

Die Konvertierung ist einfach:

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

Timbo
quelle
3

Das Konvertieren ist einfach:

std::string myString;

LPCSTR lpMyString = myString.c_str();

Hier ist zu beachten, dass c_str keine Kopie von myString zurückgibt, sondern nur einen Zeiger auf die Zeichenfolge, die std :: string umschließt. Wenn Sie eine Kopie möchten / benötigen, müssen Sie diese selbst mit strcpy erstellen.

Nick Haddad
quelle
1

Der einfachste Weg, a std::stringin a umzuwandeln , LPWSTRist meiner Meinung nach:

  1. Konvertieren Sie die std::stringin astd::vector<wchar_t>
  2. Nehmen Sie die Adresse des ersten wchar_tim Vektor.

std::vector<wchar_t>hat einen ctor mit Vorlagen, der zwei Iteratoren benötigt, z. B. den std::string.begin()und den .end()Iterator. Dies konvertiert jedoch jedes Zeichen in ein wchar_t. Dies ist nur gültig, wenn das std::stringASCII oder Latin-1 enthält, da Unicode-Werte Latin-1-Werten ähneln. Wenn es CP1252 oder Zeichen aus einer anderen Codierung enthält, ist es komplizierter. Sie müssen dann die Zeichen konvertieren.

MSalters
quelle
Warum nicht verwenden std::wstring?
Timmmm
@Timmmm: C ++ 11 hat die Spezifikation verschärft, da die Implementierungen die alten Regeln nicht ausnutzten. Heute wäre das in Ordnung.
MSalters
1
std::string myString("SomeValue");
LPSTR lpSTR = const_cast<char*>(myString.c_str());

myString ist die Eingabezeichenfolge und lpSTR ist das LPSTR- Äquivalent.

Nani
quelle