134 votes

Comment convertir std::string en LPCSTR ?

Comment puis-je convertir un std::string a LPCSTR ? Par ailleurs, comment puis-je convertir un std::string a LPWSTR ?

Je suis totalement confus avec ces LPCSTR LPSTR LPWSTR y LPCWSTR .

Sont LPWSTR y LPCWSTR la même chose ?

175voto

Nick Meyer Points 14502

Appelez c_str() pour obtenir un const char * ( LPCSTR ) 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 - Pointeur (long) vers une chaîne de caractères Unicode (large). wchar_t *

LPCWSTR - Pointeur (long) vers une chaîne de caractères constante Unicode (large). const wchar_t *

LPTSTR - Pointeur (long) vers une chaîne de caractères TCHAR (Unicode si UNICODE est défini, ANSI sinon) -. TCHAR *

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

Vous pouvez ignorer la partie L (long) des noms - c'est un vestige de Windows 16 bits.

127voto

Lou Franco Points 48823

str.c_str() vous donne un const char * qui est un LPCSTR (Long Pointer to Constant STRing) -- signifie que c'est un pointeur vers un 0 chaîne de caractères terminée. W signifie une chaîne large (composée de wchar_t au lieu de char ).

5 votes

Petit point délicat : sur x64, LPCSTR serait un pointeur 64 bits vers une chaîne (constante) à terminaison nulle.

35voto

Charles Bailey Points 244082

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

LPCSTR : pointeur vers une chaîne de caractères constants à terminaison nulle de char

LPSTR : pointeur vers une chaîne de caractères à terminaison nulle de type char (souvent, un tampon est transmis et utilisé comme paramètre de sortie).

LPCWSTR : pointeur vers une chaîne de caractères à terminaison nulle de const. wchar_t

LPWSTR : pointeur vers une chaîne de caractères à terminaison nulle, de type wchar_t (souvent, un tampon est transmis et utilisé comme paramètre de sortie).

Pour "convertir" un std::string à un LPCSTR dépend du contexte exact, mais généralement, appeler .c_str() est suffisante.

Ça 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 à la std::string et ne sera valide que jusqu'à la prochaine modification ou destruction de la chaîne.

Pour convertir un std::string à un LPWSTR est plus compliqué. Vouloir un LPWSTR implique que vous avez besoin d'un tampon modifiable et vous devez également vous assurer que vous comprenez ce que codage des caractères le site std::string utilise. Si le std::string contient une chaîne de caractères utilisant l'encodage par défaut du système (en supposant qu'il s'agit de Windows, ici), vous pouvez alors trouver la longueur du large tampon de caractères requis et effectuer le transcodage en utilisant MultiByteToWideChar (une fonction de l'API Win32).

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

24voto

Kirill V. Lyadvinsky Points 47627

Utilisation de LPWSTR vous pourriez changer le contenu de la chaîne où elle pointe. Utilisation de LPCWSTR vous ne pouviez pas changer le contenu de la chaîne vers laquelle elle 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 est juste un pointeur sur la chaîne originale. Vous ne devriez pas la renvoyer de la fonction en utilisant l'exemple ci-dessus. Pour obtenir une chaîne non temporaire LPWSTR vous devriez faire une copie de la chaîne originale sur le tas. Vérifiez l'exemple 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
}

5voto

Joel Points 312

Le site MultiByteToWideChar la réponse que Charles Bailey a donnée est la bonne. Parce que LPCWSTR est juste un typedef pour const WCHAR* , widestr dans le code d'exemple, peut être utilisé partout où un LPWSTR est prévu ou lorsqu'un LPCWSTR est attendu.

Une petite modification 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 même, si vous devez travailler avec des chaînes larges pour commencer, vous pouvez utiliser std::wstring au lieu de std::string . Si vous voulez travailler avec le système Windows TCHAR vous pouvez utiliser std::basic_string<TCHAR> . Conversion de std::wstring a LPCWSTR ou de std::basic_string<TCHAR> a LPCTSTR est juste une question d'appeler c_str . C'est lorsque vous passez d'un caractère ANSI à un caractère UTF-16 que le problème se pose. MultiByteToWideChar (et son inverse WideCharToMultiByte ) entre en jeu.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X