2008-10-19 10 views
48

ich die Dokumentation auf WideCharToMultiByte gelesen habe, aber ich bin auf diesem Parameter fest:Wie verwenden Sie richtig WideCharToMultiByte

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

Ich bin nicht ganz sicher, wie man richtig um die Variable zu initialisieren und ihn in Die Funktion

+15

Gibt es einen Grund, warum Sie Fragen zu stellen scheinen, aber keine Antworten akzeptieren? Es ist normalerweise eine gute Übung auf diesen Seiten, gute Antworten mit einem Feedback zu belohnen, in Anerkennung der Zeit, die die Leute investieren, um Ihre Frage zu beantworten. Sie haben unten ein paar sehr gute Antworten ... (Nudge) –

Antwort

16

Sie verwenden den Parameter lpMultiByteStr [out], indem Sie ein neues char-Array erstellen. Dann übergeben Sie dieses Char-Array, um es gefüllt zu bekommen. Sie müssen nur die Länge der Zeichenfolge + 1 initialisieren, damit nach der Konvertierung eine nullterminierte Zeichenfolge angezeigt wird.

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

#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 in der Dokumentation, wenn Sie sehen, dass es einen Parameter aufweist, der ein Zeiger auf einen Typ ist, und sie sagen, es eine aus Variable ist, werden Sie diese Art zu schaffen, und dann einen Zeiger darauf übergeben. Die Funktion wird diesen Zeiger verwenden, um Ihre Variable zu füllen.

So kann man dies 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; 
} 
+4

Der Code sollte berücksichtigen, dass die Anzahl der Bytes in der Multibyte-Zeichenkette mehr als die Anzahl der Zeichen in der breiten Zeichenfolge sein kann. Ein einzelnes breites Zeichen kann 2 oder mehr Bytes in der Multibyte-Zeichenkette ergeben, abhängig von den beteiligten Codierungen. –

+0

Können Sie mir ein Beispiel geben? –

+0

Als Beispiel kommen asiatische Zeichen in Betracht, aber es hängt wirklich von der Codepage ab, die für die Konvertierung verwendet wird. In Ihrem Beispiel wäre das wahrscheinlich kein Problem, weil jedes Nicht-ANSI-Zeichen durch ein Fragezeichen ersetzt würde. –

32

auf der von Brian R. Bondy bereitgestellt answer Ausarbeiten: ein Beispiel Hier ist, warum Sie zeigt einfach nicht den Ausgabepuffer auf die Anzahl der breiten Zeichen Größe in der Quelle string:

#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 
+0

Ein hervorragendes Beispiel für einen wichtigen und oft vernachlässigten Aspekt der Umwandlung von Codepage/Codierung! –

+0

-1 Das OP fragt nach Hilfe zum Parameter lpMultiByteStr. Diese Antwort beantwortet nicht das OP, es ist eine Tangente zu einer anderen veröffentlichten Antwort. –

+2

@ Error454: Sie hatten keine Kommentare im Jahr 2008. Markieren Sie es einfach. – Ryan

95

Hier sind ein paar Funktionen (basierend auf Brian Bondys Beispiel), die WideCharToMultiByte und MultiByteToWideChar verwenden, um zwischen std :: wstring und std :: string mit utf8 zu konvertieren, um keine Daten zu verlieren.

// 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; 
} 
+4

Es sollte beachtet werden, dass vor C++ 11 std :: string und std :: wstring nicht garantiert wurden um ihr Gedächtnis zusammenhängend zu haben. –

+1

Ich bezweifle ernsthaft, dass es jemals eine kommerziell verfügbare stl-Implementierung gab, die keine zusammenhängenden Vektoren hat. Die Tatsache, dass zusammenhängenden Speicher in der ersten C++ - Spezifikation nicht erforderlich war, war ein Versehen: http://herbsutter.com/2008/04/07/cringe-not-vectors-are-guaranteed-to-be-contiguous/ – tfinniga

+1

@ tfinniga Der vorherige Kommentar war über ** Strings **, nicht Vektoren. Es ist nicht garantiert, dass Zeichenfolgen in C++ 98 zusammenhängend sind (nicht das Ergebnis von Sutter), obwohl alle realen Implementierungen [zusammenhängend] sind (http://stackoverflow.com/questions/1986966/does- s0-Punkt-zu-zusammenhängenden Zeichen-in-a-stdstring). – user4815162342