73 votes

Comment utilisez-vous correctement WideCharToMultiByte

J'ai lu la documentation ici:

http://msdn.microsoft.com/en-us/library/ms776420 (VS.85) .aspx

Je suis bloqué sur ce paramètre:

lpMultiByteStr [out] Pointeur sur un tampon qui reçoit la chaîne convertie.

Je ne sais pas trop comment initialiser correctement la variable et l'introduire dans la fonction

142voto

tfinniga Points 3550

Voici quelques fonctions (basées sur l'exemple de Brian Bondy) qui utilisent WideCharToMultiByte et MultiByteToWideChar pour convertir std :: wstring et std :: string en utilisant utf8 pour ne perdre aucune donnée.

 // Convert a wide Unicode string to an UTF8 string
std::string utf8_encode(const std::wstring &wstr)
{
    int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL);
    std::string strTo( size_needed, 0 );
    WideCharToMultiByte                  (CP_UTF8, 0, &wstr[0], (int)wstr.size(), &strTo[0], size_needed, NULL, NULL);
    return strTo;
}

// Convert an UTF8 string to a wide Unicode String
std::wstring utf8_decode(const std::string &str)
{
    int size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0);
    std::wstring wstrTo( size_needed, 0 );
    MultiByteToWideChar                  (CP_UTF8, 0, &str[0], (int)str.size(), &wstrTo[0], size_needed);
    return wstrTo;
}
 

37voto

Michael Burr Points 181287

En développant la réponse fournie par Brian R. Bondy: Voici un exemple qui montre pourquoi vous ne pouvez pas simplement dimensionner le tampon de sortie en fonction du nombre de caractères larges de la chaîne source:

 #include <windows.h>
#include <stdio.h>
#include <wchar.h>
#include <string.h>

/* string consisting of several Asian characters */
wchar_t wcsString[] = L"\u9580\u961c\u9640\u963f\u963b\u9644";

int main() 
{

    size_t wcsChars = wcslen( wcsString);

    size_t sizeRequired = WideCharToMultiByte( 950, 0, wcsString, -1, 
                                               NULL, 0,  NULL, NULL);

    printf( "Wide chars in wcsString: %u\n", wcsChars);
    printf( "Bytes required for CP950 encoding (excluding NUL terminator): %u\n",
             sizeRequired-1);

    sizeRequired = WideCharToMultiByte( CP_UTF8, 0, wcsString, -1,
                                        NULL, 0,  NULL, NULL);
    printf( "Bytes required for UTF8 encoding (excluding NUL terminator): %u\n",
             sizeRequired-1);
}
 

Et la sortie:

 Wide chars in wcsString: 6
Bytes required for CP950 encoding (excluding NUL terminator): 12
Bytes required for UTF8 encoding (excluding NUL terminator): 18
 

20voto

Brian R. Bondy Points 141769

Vous utilisez le lpMultiByteStr [out] paramètre par la création d'un nouveau tableau de char. À vous ensuite de passer ce char tableau pour obtenir qu'il est rempli. Vous avez seulement besoin d'initialiser la longueur de la chaîne + 1, de sorte que vous pouvez avoir une chaîne terminée par null après la conversion.

Voici un couple d'utiles fonctions d'assistance pour vous, ils montrent l'utilisation de tous les paramètres.

#include <string>

std::string wstrtostr(const std::wstring &wstr)
{
    // Convert a Unicode string to an ASCII string
    std::string strTo;
    char *szTo = new char[wstr.length() + 1];
    szTo[wstr.size()] = '\0';
    WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, szTo, (int)wstr.length(), NULL, NULL);
    strTo = szTo;
    delete[] szTo;
    return strTo;
}

std::wstring strtowstr(const std::string &str)
{
    // Convert an ASCII string to a Unicode String
    std::wstring wstrTo;
    wchar_t *wszTo = new wchar_t[str.length() + 1];
    wszTo[str.size()] = L'\0';
    MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, wszTo, (int)str.length());
    wstrTo = wszTo;
    delete[] wszTo;
    return wstrTo;
}

--

À tout moment dans la documentation quand vous voyez qu'il a un paramètre qui est un pointeur vers un type, et ils vous disent que c'est une variable, vous aurez envie de créer ce type, et puis la passer dans un pointeur. La fonction va utiliser le pointeur pour remplir votre variable.

Pour que vous compreniez mieux:

//pX is an out parameter, it fills your variable with 10.
void fillXWith10(int *pX)
{
  *pX = 10;
}

int main(int argc, char ** argv)
{
  int X;
  fillXWith10(&X);
  return 0;
}

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