Comment puis-je convertir un std::string
à LPCSTR
? Aussi, comment puis-je convertir un std::string
à LPWSTR
?
Je suis totalement confondu avec ces LPCSTR
LPSTR
LPWSTR
et LPCWSTR
.
Est-ce que LPWSTR
et LPCWSTR
sont les mêmes?
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
).
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.
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;
}
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
}
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.
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.
La conversion est simple:
std :: string str; LPCSTR lpcstr = str.c_str ();
La meilleure façon de convertir un std::string
En un LPWSTR
est à mon avis:
std::string
En un std::vector<wchar_t>
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.