web-dev-qa-db-fra.com

Comment utilisez-vous correctement WideCharToMultiByte

J'ai lu la documentation sur WideCharToMultiByte , mais je suis bloqué sur ce paramètre:

lpMultiByteStr
[out] Pointer to a buffer that receives the converted string.

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

57
Obediah Stane

Voici quelques fonctions (basées sur l'exemple de Brian Bondy) qui utilisent WideCharToMultiByte et MultiByteToWideChar pour convertir entre 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)
{
    if( wstr.empty() ) return std::string();
    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)
{
    if( str.empty() ) return std::wstring();
    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;
}
116
tfinniga

Élaboration sur le réponse fourni par Brian R. Bondy: Voici un exemple qui montre pourquoi vous ne pouvez pas simplement dimensionner le tampon de sortie au nombre de caractères larges dans 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
32
Michael Burr

Vous utilisez le paramètre lpMultiByteStr [out] en créant un nouveau tableau de caractères. Vous passez ensuite ce tableau de caractères pour le remplir. Il vous suffit d'initialiser la longueur de la chaîne + 1 pour pouvoir avoir une chaîne terminée par un caractère nul après la conversion.

Voici quelques fonctions d'aide utiles pour vous, elles 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 lorsque vous voyez qu'il a un paramètre qui est un pointeur vers un type, et qu'ils vous disent que c'est une variable de sortie, vous voudrez créer ce type, puis lui passer un pointeur. La fonction utilisera ce pointeur pour remplir votre variable.

Vous pouvez donc mieux comprendre cela:

//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;
}
18
Brian R. Bondy