web-dev-qa-db-fra.com

Comment convertir std :: string en LPCSTR?

Comment puis-je convertir un std::string à LPCSTR? Aussi, comment puis-je convertir un std::string à LPWSTR?

Je suis totalement confondu avec ces LPCSTRLPSTRLPWSTR et LPCWSTR.

Est-ce que LPWSTR et LPCWSTR sont les mêmes?

108
Cute

str.c_str() vous donne un const char *, qui est un LPCSTR (long pointeur sur une chaîne constante) - signifie que c'est un pointeur sur un 0 chaîne de caractères terminée. W signifie chaîne large (composé de wchar_t au lieu de char).

110
Lou Franco

Appelez c_str() pour obtenir un const char * (LPCSTR) à partir d'un std::string.

Tout est dans le nom:

LPSTR - (long) pointeur sur la chaîne - char *

LPCSTR - (long) pointeur sur la chaîne constante - const char *

LPWSTR - (long) pointeur sur la chaîne Unicode (large) - wchar_t *

LPCWSTR - (long) pointeur sur la chaîne constante Unicode (large) - const wchar_t *

LPTSTR - (long) pointeur sur TCHAR (Unicode si UNICODE est défini, ANSI sinon) string - TCHAR *

LPCTSTR - (long) pointeur sur la chaîne TCHAR constante - const TCHAR *

Vous pouvez ignorer la partie L (longue) des noms - il s'agit d'une sauvegarde de Windows 16 bits.

147
Nick Meyer

Ce sont des typedefs définis par Microsoft qui correspondent à:

LPCSTR: pointeur sur la chaîne const terminée par null de char

LPSTR: pointeur sur la chaîne de caractères terminée par un caractère nul de char (un tampon est souvent passé et utilisé comme paramètre de "sortie")

LPCWSTR: pointeur sur la chaîne terminée par null de const wchar_t

LPWSTR: pointeur sur la chaîne terminée par null de wchar_t (Un tampon est souvent passé et utilisé comme paramètre de "sortie")

Pour "convertir" un std::string En LPCSTR, cela dépend du contexte exact, mais il suffit généralement d'appeler .c_str().

Cela marche.

void TakesString(LPCSTR param);

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

Notez que vous ne devriez pas essayer de faire quelque chose comme ça.

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

Le tampon renvoyé par .c_str() appartient à l'instance std::string Et ne sera valide que jusqu'à ce que la chaîne soit modifiée ou détruite.

Convertir un std::string En un LPWSTR est plus compliqué. Vouloir un LPWSTR implique que vous ayez besoin d’un tampon modifiable et que vous sachiez bien comprendre ce que codage de caractères utilise le std::string. Si le std::string Contient une chaîne utilisant le codage par défaut du système (en supposant que Windows, ici), vous pouvez trouver la longueur du tampon de caractères larges requis et effectuer le transcodage à l'aide de MultiByteToWideChar (une API Win32 une fonction).

par exemple.

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

En utilisant LPWSTR, vous pouvez modifier le contenu de la chaîne là où il pointe. En utilisant LPCWSTR, vous ne pouviez pas changer le contenu de la chaîne où il pointe.

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 n'est qu'un pointeur sur la chaîne d'origine. Vous ne devriez pas le retourner de function en utilisant l'exemple ci-dessus. Pour obtenir non temporaire LPWSTR, vous devriez faire une copie de la chaîne originale sur le tas. Vérifiez l'échantillon ci-dessous:

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

La MultiByteToWideChar réponse donnée par Charles Bailey est la bonne. Parce que LPCWSTR est juste un typedef pour const WCHAR*, widestr dans l'exemple de code, il peut être utilisé partout où un LPWSTR est attendu ou un LPCWSTR est attendu.

Un Tweak mineur serait d'utiliser std::vector<WCHAR> au lieu d’un tableau géré manuellement:

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

De plus, si vous devez commencer par utiliser des chaînes larges, vous pouvez utiliser std::wstring au lieu de std::string. Si vous voulez utiliser le type Windows TCHAR, vous pouvez utiliser std::basic_string<TCHAR>. Conversion de std::wstring à LPCWSTR ou de std::basic_string<TCHAR> à LPCTSTR consiste simplement à appeler c_str. C'est lorsque vous passez de caractères ANSI à UTF-16 que MultiByteToWideChar (et son inverse WideCharToMultiByte) entre en jeu.

4
Joel

La conversion est simple:

std::string myString;

LPCSTR lpMyString = myString.c_str();

Une chose à faire ici est que c_str ne renvoie pas une copie de myString, mais simplement un pointeur sur la chaîne de caractères que std :: string renvoie. Si vous voulez/avez besoin d'une copie, vous devrez en créer une vous-même en utilisant strcpy.

2
Nick Haddad

La conversion est simple:

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

1
Timbo

La meilleure façon de convertir un std::string En un LPWSTR est à mon avis:

  1. Convertir le std::string En un std::vector<wchar_t>
  2. Prenez l'adresse du premier wchar_t Dans le vecteur.

std::vector<wchar_t> A un acteur basé sur un modèle qui prendra deux itérateurs, tels que les itérateurs std::string.begin() et .end(). Ceci convertira chaque caractère en un wchar_t, Cependant. Cela n’est valable que si le std::string Contient ASCII ou Latin-1, en raison de la façon dont les valeurs Unicode ressemblent aux valeurs Latin-1. S'il contient du CP1252 ou des caractères de tout autre codage, c'est plus compliqué, il faudra ensuite convertir les personnages.

1
MSalters