J'essaie de convertir un programme pour les caractères multi-octets en Unicode.
J'ai parcouru le programme et précédé les littéraux de chaîne avec L
pour qu'ils ressemblent à L"string"
.
Cela a fonctionné mais il me reste maintenant une chaîne de style C qui ne sera pas conforme. J'ai essayé le L
et le mettre dans TEXT()
mais le L
est ajouté au nom de la variable - pas la chaîne - si j'utilise TEXT()
.
J'ai essayé d'en faire un TCHAR
mais il se plaint qu'il ne peut pas convertir un TCHAR
en un char *
.
Avec quelles options me reste-t-il?
Je sais que C et C++ sont différents. Il s'agit d'une ancienne bibliothèque C interne qui est utilisée dans les projets C++ depuis plusieurs années maintenant.
Le std::mbstowcs
est la fonction que vous recherchez:
char text[] = "something";
wchar_t wtext[20];
mbstowcs(wtext, text, strlen(text)+1);//Plus null
LPWSTR ptr = wtext;
pour string
s,
string text = "something";
wchar_t wtext[20];
mbstowcs(wtext, text.c_str(), text.length());//includes null
LPWSTR ptr = wtext;
-> ED: le préfixe "L" ne fonctionne que sur les littéraux de chaîne, pas sur les variables. <-
La meilleure façon d'utiliser mbstowcs
est de l'appeler deux fois pour trouver la longueur du résultat:
const char * cs = <your input char*>
size_t wn = mbsrtowcs(NULL, &cs, 0, NULL);
// error if wn == size_t(-1)
wchar_t * buf = new wchar_t[wn + 1](); // value-initialize to 0 (see below)
wn = mbsrtowcs(buf, &cs, wn + 1, NULL);
// error if wn == size_t(-1)
assert(cs == NULL); // successful conversion
// result now in buf, return e.g. as std::wstring
delete[] buf;
N'oubliez pas d'appeler setlocale(LC_CTYPE, "");
au début de votre programme!
L'avantage par rapport à Windows MultiByteToWideChar
est qu'il s'agit d'un C entièrement standard, bien que sous Windows, vous préfériez quand même la fonction API Windows.
J'encapsule généralement cette méthode, ainsi que l'autre, dans deux fonctions de conversion string
-> wstring
et wstring
-> string
. Si vous ajoutez également des surcharges triviales string
-> string
et wstring
-> wstring
, vous pouvez facilement écrire du code qui se compile avec Winapi TCHAR
typedef dans n'importe quel paramètre.
[ Edit: ] J'ai ajouté une initialisation nulle à buf
, au cas où vous prévoyez d'utiliser directement le tableau C. Je renvoie généralement le résultat sous la forme std::wstring(buf, wn)
, mais faites attention si vous prévoyez d'utiliser des tableaux à terminaison nulle de style C. [/]
Dans un environnement multithread, vous devez passer un état de conversion thread-local à la fonction comme paramètre final (actuellement invisible).
Voici un petite diatribe à moi sur ce sujet.
Cette version, à l'aide de la fonction API Windows MultiByteToWideChar()
, gère l'allocation de mémoire pour les chaînes d'entrée arbitrairement longues.
int lenA = lstrlenA(input);
int lenW = ::MultiByteToWideChar(CP_ACP, 0, input, lenA, NULL, 0);
if (lenW>0)
{
output = new wchar_t[lenW];
::MultiByteToWideChar(CP_ACP, 0, input, lenA, output, lenW);
}
Vous pouvez utiliser CString
, CStringA
, CStringW
pour effectuer des conversions automatiques et effectuer des conversions entre ces types. De plus, vous pouvez également utiliser CStrBuf
, CStrBufA
, CStrBufW
pour obtenir des chaînes modifiables du modèle RAII
J'utilise ce qui suit dans VC++ et cela fonctionne comme un charme pour moi.
CA2CT(charText)