web-dev-qa-db-de.com

Wie konvertiere ich char * nach wchar_t *?

Ich habe versucht, eine Funktion wie diese zu implementieren, aber leider funktioniert es nicht:

const wchar_t *GetWC(const char *c)
{
    const size_t cSize = strlen(c)+1;
    wchar_t wc[cSize];
    mbstowcs (wc, c, cSize);

    return wc;
}

Mein Hauptziel hierbei ist es, normale Zeichenfolgen in eine Unicode-Anwendung integrieren zu können. Jeder Rat, den ihr anbieten könnt, wird sehr geschätzt.

48
AutoBotAM

Verwenden Sie ein std::wstring Anstelle eines C99-Arrays mit variabler Länge. Der aktuelle Standard garantiert einen zusammenhängenden Puffer für std::basic_string. Z.B.,

std::wstring wc( cSize, L'#' );
mbstowcs( &wc[0], c, cSize );

C++ unterstützt keine C99-Arrays variabler Länge. Wenn Sie Ihren Code also als reines C++ kompilieren, wird er nicht einmal kompiliert.

Mit dieser Änderung sollte Ihr Funktionsrückgabetyp auch std::wstring Sein.

Denken Sie daran, das relevante Gebietsschema in main festzulegen.

Zum Beispiel setlocale( LC_ALL, "" ).

Prost & Hth.,

31

In Ihrem Beispiel ist wc eine lokale Variable, deren Zuordnung aufgehoben wird, wenn der Funktionsaufruf endet. Dies versetzt Sie in ein undefiniertes Verhaltensgebiet.

Die einfache Lösung lautet wie folgt:

const wchar_t *GetWC(const char *c)
{
    const size_t cSize = strlen(c)+1;
    wchar_t* wc = new wchar_t[cSize];
    mbstowcs (wc, c, cSize);

    return wc;
}

Beachten Sie, dass der aufrufende Code diesen Speicher freigeben muss, da sonst ein Speicherverlust auftritt.

36
Andrew Shepherd
const char* text_char = "example of mbstowcs";
size_t length = strlen(text_char );

Anwendungsbeispiel "mbstowcs"

std::wstring text_wchar(length, L'#');

//#pragma warning (disable : 4996)
// Or add to the preprocessor: _CRT_SECURE_NO_WARNINGS
mbstowcs(&text_wchar[0], text_char , length);

Anwendungsbeispiel "mbstowcs_s"

Microsoft schlägt vor, "mbstowcs_s" anstelle von "mbstowcs" zu verwenden.

Links:

Beispiel Mbstowcs

mbstowcs_s, _mbstowcs_s_l

wchar_t text_wchar[30];

mbstowcs_s(&length, text_wchar, text_char, length);
4
Maks

Sie geben die Adresse einer lokalen Variablen zurück, die auf dem Stapel zugeordnet ist. Wenn Ihre Funktion zurückkehrt, wird der Speicher für alle lokalen Variablen (wie z. B. wc) freigegeben und kann sofort von etwas anderem überschrieben werden.

Um dies zu beheben, können Sie die Größe des Puffers an GetWC übergeben, aber dann haben Sie so ziemlich die gleiche Schnittstelle wie mbstowcs selbst. Oder Sie können einen neuen Puffer in GetWC zuweisen und einen Zeiger darauf zurückgeben, sodass der Aufrufer die Zuordnung des Puffers aufheben kann.

2
Greg Hewgill

Ihr Problem hat nichts mit Codierungen zu tun, es ist eine einfache Sache, C++ zu verstehen. Sie geben einen Zeiger auf eine lokale Variable aus Ihrer Funktion zurück, die zum Zeitpunkt ihrer Verwendung den Gültigkeitsbereich verlassen hat, wodurch undefiniertes Verhalten erstellt wird (dh ein Programmierfehler).

Befolgen Sie diese goldene Regel: "Wenn Sie nackte Zeichenzeiger verwenden, tun Sie es falsch. (Außer wenn Sie es nicht sind.)"

Ich habe zuvor gepostet etwas Code für die Konvertierung und die Kommunikation der Ein- und Ausgabe in C++ std::string und std::wstring Objekte.

1
Kerrek SB

Ich habe so etwas gemacht. Die ersten beiden Nullen sind, weil ich nicht weiß, welche Arten von ASCII-Typ-Dingen dieser Befehl von mir verlangt. Ich hatte das allgemeine Gefühl, ein temporäres Zeichen-Array zu erstellen. übergeben Sie in der breiten Zeichenfolge. Boom. Es klappt. Mit +1 wird sichergestellt, dass das Null-Abschlusszeichen an der richtigen Stelle steht.

char tempFilePath[MAX_PATH] = "I want to convert this to wide chars";

int len = strlen(tempFilePath);

// Converts the path to wide characters
    int needed = MultiByteToWideChar(0, 0, tempFilePath, len + 1, strDestPath, len + 1);
1
Gandalf458