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