Wo kommt die 13 her?



  • Hallo,

    ich habe mir eine kleine Funktion geschrieben, die ein unsigned char-Array in eine Datei schreibt.

    Sie sieht folgendermaßen aus:

    static void WriteFile(std::string fileName, unsigned char* buffer, unsigned int bufSize)
    {
      std::ofstream myfile;
      myfile.open(fileName.c_str());
      for(unsigned int f1=0;f1<bufSize;f1++)
      {
        myfile << buffer[f1];
      }
      myfile.close();
    }
    

    Nun wollte ich ein unsigned char-Array mit 800030 Elementen in eine Datei schreiben. Ich hab also der Funktion WriteFile als Parameter 2 das Array und als Parameter 3 800030 übergeben. Nach dem Schreiben war die Datei aber 801230 anstatt 800030 Bytes groß. Nach einiger Zeit der Fehlersuche hab ich dann gesehen, dass er z.B. nach Byte 4066 (einem 0A) noch ein 0D, also ein Leerzeichen eingefügt hatte. Und das insgesamt 1200 Mal. Der Debugger zeigt mir aber an, dass nach Beendigung der for-Schleife in der WriteFile-Funktion f1 den Wert 800029 hatte.

    Wo kommt jetzt also dieses Leerzeichen her, und wie kann man jetzt die "WriteFile"-Funktion dahingegen umbauen, dass dieses Leerzeichen nicht mehr dort auftritt?



  • In deinem Code sehe ich keinen Fehler. Allerdings kann man die Funktion viel kuerzer schreiben:

    static void WriteFile(std::string fileName, unsigned char* buffer, unsigned int bufSize)
    {
        std::ofstream os(fileName);
        os.write(reinterpret_cast<char*>(buffer), bufSize);
    }
    


  • Taeli schrieb:

    wie kann man jetzt die "WriteFile"-Funktion dahingegen umbauen, dass dieses Leerzeichen nicht mehr dort auftritt?

    static void WriteFile(std::string fileName, unsigned char* buffer, unsigned int bufSize)
    {
      std::ofstream myfile;
      myfile.open(fileName.c_str(), ios_base::out | ios_base::binary);
      myfile.write(buffer, bufsize);
      myfile.close();
    }
    


  • Wenn du Binärdaten in Dateien schreiben willst, musst du den Stream im Binärmodus öffnen.

    std::ofstream myfile(filename.c_str, std::ios::binary);
    

    Ohne diese Angabe wird die Datei im Textmodus geöffnet, dann werden automatisch alle Zeilenendezeichen ('\n') in systemspezifische Codierungen überführt. Unter Windows ist das eine Sequenz aus 13 (Carriage Return) und 10 (Line Feed), auch CR+LF genannt. Unter Linux ist Text=Binärmodus. Bei noch anderen Systemen ist es vielleicht was ganz anderes...



  • Kellerautomat schrieb:

    In deinem Code sehe ich keinen Fehler.

    Das Problem dürfte sein, dass der << Operator aus einem '\n' die Bytefolge für CR und LF macht.



  • Bashar schrieb:

    Wenn du Binärdaten in Dateien schreiben willst, musst du den Stream im Binärmodus öffnen.

    std::ofstream myfile(filename.c_str, std::ios::binary);
    

    Ohne diese Angabe wird die Datei im Textmodus geöffnet, dann werden automatisch alle Zeilenendezeichen ('\n') in systemspezifische Codierungen überführt. Unter Windows ist das eine Sequenz aus 13 (Carriage Return) und 10 (Line Feed), auch CR+LF genannt. Unter Linux ist Text=Binärmodus. Bei noch anderen Systemen ist es vielleicht was ganz anderes...

    Ah, super, jetzt klappt es!

    Warum ist das Zeilenende bei Windows eigentlich mit 0D0A codiert? Ist auf jeden Fall ziemlich nervig, wenn man eine auf einem Linux-OS geschriebene Textdatei auf Windows bearbeiten möchte.



  • Taeli schrieb:

    Warum ist das Zeilenende bei Windows eigentlich mit 0D0A codiert?

    Hysterical raisins. Das war halt schon bei DOS so, und vermutlich war es auch bei CP/M so. Das kommt aus der Zeit, als das noch echte Steuerzeichen für Drucker waren. Schonmal eine alte Schreibmaschine in Aktion gesehen? Am Zeilenende schiebt man den Wagen wieder nach rechts und dreht dabei die Walze eine Zeile weiter.

    Die Frage ist eher, warum man bei Unix die Weitsicht hatte, das nicht zu übernehmen. 🙂

    Hier steht das ganze noch viel besser: http://en.wikipedia.org/wiki/Newline

    (edit: Man schiebt den Wagen natürlich nach rechts!)



  • Belli schrieb:

    Das Problem dürfte sein, dass der << Operator aus einem '\n' die Bytefolge für CR und LF macht.

    Achja, da war doch was. Daran habe ich noch nie gedacht, und jedes mal frage ich mich, wie vergesslich man eigentlich sein kann. 🙂


Anmelden zum Antworten