char* zu wchar_t* konvertieren



  • Hallo erstmal,

    Nach langem Nichtbenutzen von C++ melde ich mich mal wieder. Ich möchte versuchen, ein char-Array in ein wchar_t-Array zu konvertieren. Und zwar ist mein char* schon im Unicode-Format. So sieht ein String mit dem Inhalt "Hallo" zum Beispiel so aus:

    {72, 0, 97, 0, 108, 0, 108, 0, 111, 0}

    Ich habe das als char* aus einem istream ausgelesen (wistream kommt nicht in Frage, weil ich dann alle Datentypen anpassen müsste, die Datei aus der ich lese ist im Binärformat und enthält neben den Unicode-Strings noch viele andere Daten) und versuche es nun folgendermaßen umzuwandeln:

    char ndata[len];
    stream.read(ndata, len);
    wchar_t* data = new wchar_t[len/2];
    mbstowcs(data, ndata, len/2);
    
    // Zum Testen
    wcout << data << endl;
    

    Als Resultat bekomme ich jedoch nur das jeweils erste Zeichen. Da wird wohl das zweite Zeichen ein \0 sein, aber warum? Was mache ich falsch?

    Danke im Voraus!



  • Also mal abgesehen davon dass wchar_t nicht auf allen Plattformen notwendigerweise 16 Bit gross ist...

    Du kannst hier einfach memcpy() verwenden. (Vorausgesetzt eben dein Input und gewünschter Output sind beide UTF-16 bzw. beide UCS2).

    mbstowcs geht ja davon aus dass du eine multi-byte Codepage als Input hast. Du gibst mbstowcs allerdings einen (vermutlich) UTF-16 String. Kann also nicht klappen.

    Wenn du es ganz ganz korrekt machen willst (plattformunabhängig etc.), müsstest du natürlich irgendwie anders konvertieren, da es ja sein kann, dass wie oben erwähnt wchar_t eben nicht 16 Bit gross ist.
    Für Plattformen auf denen wchar_t 32 Bit gross ist, müsstest du dann z.B. eine UTF-16 -> UTF-32 Konvertierung machen.

    Also kurz: es kommt darauf an was du für Anforderungen stellst. Und auch was du über den Input-String weisst. (Wenn der z.B. immer nur Latin-I kompatible Zeichen enthält, dann ist es ganz einfach)





  • Also mal abgesehen davon dass wchar_t nicht auf allen Plattformen notwendigerweise 16 Bit gross ist...

    Und wie mir eben gerade aufgefallen ist ist das bei mir der Fall, da ist der Datentyp 32 Bit groß.

    Wenn du es ganz ganz korrekt machen willst (plattformunabhängig etc.), müsstest du natürlich irgendwie anders konvertieren, da es ja sein kann, dass wie oben erwähnt wchar_t eben nicht 16 Bit gross ist.
    Für Plattformen auf denen wchar_t 32 Bit gross ist, müsstest du dann z.B. eine UTF-16 -> UTF-32 Konvertierung machen.

    Dann werde ich wohl wirklich eine solche Konvertierung vornehmen müssen. Gibt es da einen intelligenteren (effizienteren) Weg UTF-16 in UTF-32 umzuwandeln als nach allen 2 Bytes noch 2 Null-Bytes anzuhängen?

    http://www.c-plusplus.net/forum/viewtopic-var-t-is-39492.html

    Hier wird aber von 8 Bit pro Zeichen ausgegangen, wie ich das sehe.



  • UTF-16 in UTF-32

    was hat das mit char* nach wchar_t* zu tun?

    utf-32 ist das gleiche wie ucs4 - also in der windows-welt nen long und zumindest unter unix reicht imho wchar_t .
    du nimmst also utf-16 (was an sich schon mind. wchar_t (oder short ) ist) und guckst die ersten paar bit durch (wenn das 4. oder 5. bit gesetzt ist) und dann weist du, ob du zwei dieser utf16-zeichen zusammensetzen musst oder ob du gar nichts machen musst...
    verständlich?



  • [quote="Alemarius Nexus"]

    ...
    Dann werde ich wohl wirklich eine solche Konvertierung vornehmen müssen. Gibt es da einen intelligenteren (effizienteren) Weg UTF-16 in UTF-32 umzuwandeln als nach allen 2 Bytes noch 2 Null-Bytes anzuhängen?

    typedef long wchar_32;
    
        wchar_t a[6] = L"Hallo";
        wchar_32 b[6];
    
        wchar_t* Ptr1 = a;
        wchar_32* Ptr2 = b;
    
        while (*Ptr2++ = static_cast<wchar_32>(*Ptr1++));  // Habe fertig oder?
    


  • nö, so einfach geht das nicht - siehe meinen post


Anmelden zum Antworten