web-dev-qa-db-fra.com

Convertir char * en LPWSTR

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.

33
Skeith

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 strings,

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

41
Raphael R.

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.

12
Kerrek SB

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);
} 
4
David Heffernan

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

1
Ajay

J'utilise ce qui suit dans VC++ et cela fonctionne comme un charme pour moi.

CA2CT(charText)
0
MoraRockey