it-swarm.com.de

Wie benutzt man WideCharToMultiByte richtig?

Ich habe die Dokumentation zu WideCharToMultiByte gelesen, bin aber bei diesem Parameter festgefahren:

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

Ich bin nicht ganz sicher, wie ich die Variable richtig initialisieren und in die Funktion einspeisen soll

57
Obediah Stane

Hier sind einige Funktionen (basierend auf dem Beispiel von Brian Bondy), die WideCharToMultiByte und MultiByteToWideChar verwenden, um mit utf8 zwischen std :: wstring und std :: string zu konvertieren, damit keine Daten verloren gehen.

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

Erläuterung des Antwort von Brian R. Bondy: Hier ist ein Beispiel, das zeigt, warum Sie den Ausgabepuffer nicht einfach auf die Anzahl der breiten Zeichen in der Quellzeichenfolge skalieren können:

#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);
}

Und die Ausgabe:

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

Sie verwenden den Parameter lpMultiByteStr [out], indem Sie ein neues Zeichenarray erstellen. Anschließend übergeben Sie dieses Zeichen-Array, um es zu füllen. Sie müssen nur die Länge der Zeichenfolge + 1 initialisieren, damit Sie nach der Konvertierung eine nullterminierte Zeichenfolge haben können.

Hier sind einige nützliche Hilfsfunktionen für Sie, die die Verwendung aller Parameter zeigen.

#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;
}

-

Immer wenn Sie in der Dokumentation feststellen, dass es einen Parameter gibt, der auf einen Typ verweist, und der angibt, dass es sich um eine Out-Variable handelt, möchten Sie diesen Typ erstellen und dann einen Zeiger darauf übergeben. Die Funktion verwendet diesen Zeiger, um Ihre Variable zu füllen.

So können Sie das besser verstehen:

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