Unicode in Datei schreiben, Suche leider nicht weitergeholfen



  • Guten Tag liebe Community,

    habe ein problem, dass mir Kopfzerbrechen bereitet.

    #include <fstream>
    #include <iostream>
    using namespace std;

    #ifdef UNICODE
    #define UNICODE
    #endif

    #ifdef _UNICODE
    #define _UNICODE
    #endif

    int OpenFile(/**/)
    {
    wfstream Datei;
    wchar_t filename[] = L"проккуеее.txt";
    wchar_t zeile[] = L"я_дурак!";
    Datei.open(filename, ios::app);
    Datei << zeile << endl;
    Datei.close();
    return 0;
    }

    int main()
    {
    OpenFile();
    return 0;
    }

    Das ist der Code, um den es geht. Ich bekomm meinen String nicht in die Datei geschrieben 😞
    Compiler gibt keine Warnung raus, Datei wird angelegt, die Variable hat den richtigen Wert, aber die angelegte Datei ist leer.

    Kann mir jemand erklären, woran das liegt? Ich benutz VS 2005 TEAM Edition.

    Vielen Dank im Voraus.



  • Erstmal sind deine Code-Blöcke

    #ifdef UNICODE 
    #define UNICODE 
    #endif
    

    sinnlos - fehlt da möglicherweise ein "n"?

    Und zweitens: Wie äußert sich das "die Datei ist leer"? Was zeigt der Explorer als Größe an? Kannst du die Datei per wfstream wieder einlesen und auf dem Monitor ausgeben?



  • ist die Dateigröße. Es ist ein leerer String, der eingelesen wird. Und da hat ein n gefehlt 🙂



  • Kann das vielleicht an der Codierung der Datei liegen? Muss ich explizit sagen, welchen Dateityp ich anlege?



  • Sexymaxy schrieb:

    ist die Dateigröße.

    Was ist denn das für eine Aussage?



  • //untested

    wchar_t filename[] = L"проккуеее.txt";
    wchar_t zeile[] = L"я_дурак!";
    std::ofstream file( filename, std::ios_base::binary );
    file.write( zeile, 8 );
    file.close();



  • CStoll schrieb:

    Sexymaxy schrieb:

    ist die Dateigröße.

    Was ist denn das für eine Aussage?

    0 Byte steht im Titel 🙂 habe ich dann auch gemerkt, dass man das nicht unbedingt sieht und lobe Besserung 😃



  • @ Mr Evil
    Mit wofstream klappts nicht (unicode-version des ofstream
    Genau das gleiche Resultat 😞



  • Ich vermute mal, der Compiler kennt kein Unicode und daher werden die W-Stringliterale in Deinem Quellcode zerschossen. Verwende mal Escape-Sequenzen stattdessen und schau, ob es so klappt.



  • bei mir genau das selbe

    sobald ich die russischen zeichen durch "normale" ersetz gehts

    was ma probieren kann

    diese russischen zeichen mal in einer txt kopieren - und mal in ANSI anzeigen lassen, dann kann man das kopieren

    {das es zerschossen ist sieht man schon an den dateinamen der erstellten datei}



  • Der Compiler kann an sich Unicode 🙂
    Hab es aber auch schon mit anderen probiert. Und der Dateiname wird ja richtig angegeben (dass es in russisch keinen Sinn ergibt ist mir klar, hab nur bißchen losgetippt :D, oder meinst du mit zerschossen was anderes Mr. Evil?) Und beim Debuggen übernimmt auch die variable den richtigen Wert. Dieser wird nur nicht in die Datei geschrieben. Sobald es ein char ist schon. Das heistt doch, dass die Schreibfunktion Unicode nicht verarbeitet. Aber warum, das verstehe ich nicht 😕



  • Die erzeugte Datei ist ANSI 😞
    Das wäre natürlich eine Erklärung, warum nichts drin ist, aber keine dafür, warum es eine ANSI-Datei ist



  • Bei Unicode-Dateien sollten die ersten beiden Bytes der Datei als 'FF FE' gesetzt sein (damit der Editor das Encoding erkennt).
    Ist denn wirklich die Dateigröße 0 (s. Dateieigenschaften) oder siehst du nur nichts im Editor?



  • Sexymaxy schrieb:

    Kann mir jemand erklären, woran das liegt? Ich benutz VS 2005 TEAM Edition.

    Ich hab's gerade auch probiert.
    Die Ursache für das Problem liegt in der Facette std::codecvt< wchar_t, char, int > die vom unterm fstream liegenden std::filebuf verwendet wird, um die wchar_t in eine Zeichenkette zu wandeln, die dann letztlich in die Datei geschrieben wird. Wenn der User nichts einstellt, so kann die Default-codecvt<> anscheinend nur Zeichen der aktuellen Codepage vearbeiten d.h. alles was größer ist als 255 wird als Ausgabe-Fehler interpretiert 😞

    Microsoft mag wohl kein C++, das ist nicht die erste und wohl auch nicht die letzte unschöne Erscheinung in dem Umfeld. .. und das im 10.Jahr nach der Standardisierung von C++ bei der aktuellen Entwicklungsumgebung 😡

    Die Lösung wäre: eine eigene std::codecvt< wchar_t, char, int > schreiben und vorm ersten Schreiben mit imbue in den ofstream einhängen. Für Output habe ich das selber schon gemacht, beim Input steckt auch noch ein weiterer Bug im std::filebuf ..; aber das ist eine andere Geschichte.

    Noch ein Tipp; wenn's sich vermeiden lässt, wenigstens beim Dateinamen auf Unicode-Zeichen >255 (besser >128) verzichten. Etliche Programme reagieren da allergisch.

    Gruß
    Werner



  • Die Dateigröße ist wirklich 0 Byte. Die erzeugte Datei ist auch ANSI. Wenn ich diesen text manuell in einen Unicode-Datei einfüge erhalte ich erwartungsgemäß eine Datei, die 18 byte groß ist.



  • Vielen Dank Werner Salomon,

    das ist eine Erklärung, die ich nachvollziehen kann. Leider bin ich noch nicht so sehr in C++ bewandert, so dass ich Ihre Lösung in ruhe später ausprobieren werde. Vorerst werde ich aber dann die Datei über CFile erzeugen. ähnlich, wie hier: http://www.codeproject.com/file/textfiledocument.asp
    Die Datei bekommt einen normalen Namen, das war nur zum ausprobieren 😃

    Nochmal Vielen Dank an alle.


Anmelden zum Antworten