plattformunabhängiges binäres EOL



  • Hallo,

    Ich suche eine Möglichkeit die binäre Repräsentation des EOL für die vorhandene Plattform in einen stringstream zu bekommen. Ich hatte mir das so gedacht, dass ich erstmal in einen normalen stringstream per textmode schreibe und den dann in einen binären stringstream übertrage.

    std::stringstream eol;
    	eol << std::endl;
    	std::stringstream str(std::stringstream::in|std::stringstream::out|std::stringstream::binary);
    	char temp[3] = {};
    	eol.rdbuf()->sgetn(temp, 2);
    	str.write(temp, 2);
    

    Unter Windows müsste dann ein 0D 0A rauskommen.
    Es kommt aber nur ein 0A raus. Was ist hier falsch? oder besser wie macht man es richtig?



  • Das \r(0x0D) wird m.W. nur beim Schreiben in eine Textdatei da reingewurstelt. Beim Lesen wirds wieder rausgefiltert.



  • Ich will das aber, wenn es geht, wissen ohne eine Textdatei schreiben zu müssen.



  • Braunstein schrieb:

    Ich will das aber, wenn es geht, wissen ohne eine Textdatei schreiben zu müssen.

    Geht leider nicht: http://stackoverflow.com/questions/6865398/inserting-endline-into-a-stringstream



  • Ok.
    Wo wird diese Konvertierung beim Lesen und Schreiben dann durchgeführt? Irgendwo im fstream?
    Ich habe das Ganze jetzt erstmal mit defines gelöst. Gefällt mir zwar nicht wirklich funktioniert aber.
    Jetzt kann man auch beim Mac unter Windows erzeugte Textdateien lesen.


  • Mod

    Braunstein schrieb:

    Jetzt kann man auch beim Mac unter Windows erzeugte Textdateien lesen.

    Sag doch gleich, was du vor hast, dann kann man dir auch sofort helfen: Nimm Boost Iostreams. Die haben das schon lange gelöst und viel besser als mit Makros.
    http://www.boost.org/doc/libs/1_36_0/libs/iostreams/doc/classes/newline_filter.html



  • Danke.
    boost kommt leider nicht infrage. Mein Chef hat die Verwendung verboten.
    Ich kann da aber mal reinschauen wie die das machen.



  • Braunstein schrieb:

    Danke.
    boost kommt leider nicht infrage. Mein Chef hat die Verwendung verboten.
    Ich kann da aber mal reinschauen wie die das machen.

    Darf man Fragen aus welchen Grund boost verboten ist?



  • Das ist garnicht so leicht zu sagen.
    Mein Chef misstraut erstmal grundsätzlich externen Bibliotheken bei Nicht-GUI-Anwendungen. Weiterhin misstraut er allen moderneren Features von C++ (z.Bsp. Templates). Wenn es unbedingt nötig ist geht es aber nichts was über sein Verständnis hinaus geht.
    Er will jede Zeile Code kontrollieren und verstehen können. Das geht bei boost schlicht nicht.
    Evtl. hast du jetzt eine Vorstellung was ich meine.



  • Also ist dein Chef ein Idiot, der sich weigert, sich weiterzubilden. Wuerde kuendigen.



  • @Braunstein
    Ich verstehe nicht ganz was du machen willst.

    Wenn du nur Textdateien lesen können möchtest, die auf anderen Systemen erzeugt wurden, und Boost verboten ist, UND du mit iostreams arbeiten willst/musst, ... dann schreib einen eigenen istream.

    Der kann dann beim Lesen der Daten folgende einfache Logik anwenden:

    last_ch = 0
    while (!eof)
        ch = get_next_char()
    
        if (ch == '\n' && last_ch == '\r')
            last_ch = 0           -- 2. Teil einer EOL Sequenz gefunden
        else if (ch == '\r' && last_ch == '\n')
            last_ch = 0           -- 2. Teil einer EOL Sequenz gefunden
        else if (ch == '\r' || ch == '\n')
            last_ch = ch          -- 1. Teil einer EOL Sequenz gefunden
            emit_EOL()
        else
            last_ch = 0
            emit_normal_char(ch)
    

    Damit kannst du sämtliche Textfiles lesen, du musst nichtmal wissen welche EOL Sequenz verwendet wird. Funktioniert sogar gut mit Textfiles mit "mixed EOL".

    Wenn du Textfiles klein genug sind kannst sie natürlich auch binär in einen std::string/std::vector<char> einlesen, dann eine Funktion drüberlaufen lassen die nach dem Schema oben die Newlines normalisiert, den auf diese Art "normalisierten" String dann in einen std::stringstream stecken, und dann mit dem std::stringstream weiterarbeiten.

    Und beim Schreiben kannst du direkt std::ofstream verwenden - der kümmert sich dann darum dass die für die aktuelle Plattform üblichen EOLs generiert werden.

    ----

    Was mich jetzt aber etwas verwirrt, ist: ich sehe hier nirgends die Notwendigkeit rauszubekommen was die aktuelle Plattform für nen EOL Style verwendet.

    ps: komisch dass du dann die STL verwenden darfst. Ist auch ne Library die dein Chef nicht mehr verstehen wird, und die wird auch nur von Menschen programmiert, keinen allmächtigen fehlerlosen Programmiergöttern.



  • Hallo,

    @hustbaer
    Ja das geht natürlich so. Ich wollte halt die bestehende Leseroutine nicht groß anfassen und einen Konverter davor schalten. Da hatte ich halt die Idee das auf Binärebene zu machen und da bräuchte ich halt die aktuell auf dem System verwendete Repräsentation.
    Wahrscheinlch mal wieder viel zu kompliziert gedacht.

    Bezüglich der STL hast du durchaus recht, die hat er aber verstanden. Mal abgesehen davon wäre es etwas schwierig darauf auch noch zu verzichten. dann kann ich ja gleich C machen.

    Ich mach jetzt Feierabend



  • Braunstein schrieb:

    Ja das geht natürlich so. Ich wollte halt die bestehende Leseroutine nicht groß anfassen und einen Konverter davor schalten.

    Kannst du ja. Der Code oben eignet sich auch super als Konverter.

    Da hatte ich halt die Idee das auf Binärebene zu machen und da bräuchte ich halt die aktuell auf dem System verwendete Repräsentation.

    Öh. Wieso? Eine Funktion die mit allen EOL-Varianten gleichzeitig klarkommt sollte doch reichen?



  • Hallo,

    Ich habe jetzt hustbaers Vorschlag aufgegriffen und einen Streambuffer gebastelt der die Konvertierung vornimmt. Bis jetzt scheint das auch zu funktionieren.
    Danke für alle Anregungen.


Anmelden zum Antworten