istream_iterator



  • Hallo,

    ich habe einen istream_iterator. mit diesem will ich die ersten 7 zeichen aus einer datei auslesen. das mache ich wie folgt:

    std::istream_iterator file(in); // in ist ein ifstream
    std::string str;
    for (unsigned i = 0; i < 7; ++i, ++file)
    {
      str += *file;
    }
    

    (Dateiinhalt: BLENDER_v usw.)
    das problem an der sache ist, dass nach der schleife der iterator schon beim 7. zeichen (dem '_') steht, dass heißt eins zu weit. denn wenn ich jetzt das nächste zeichen auslesen will, darf ich vorher kein ++file schreiben.
    mir fällt nicht ein, wie man das problem lösen kann, so dass der iterator nach der schleife beim 'R' stehen bleibt.

    mit schönen grüßen

    Vario-500



  • Warum willst du denn das 'R' mehrmals einlesen?

    std::istream_iterator file(in); // in ist ein ifstream
    std::string str;
    for (unsigned i = 0; i < 6; ++i, ++file)
    {
      str += *file;
    }
    str += *file
    

    Wär eine Variante ...

    mfg D3lta



  • ich will das 'R' nicht mehrmals einlesen, ich will nur der Übersichtlichkeit halber im nächsten schritt wo ich das '_' einlese, erst ++file schreiben.
    sonst kommt man ja selbst irgendwann durcheinander, wenn man das immer anders macht 😃



  • Ich würde es trotzdem so machen, wie du es nicht wolltest 😉

    mfg D3lta



  • Am übersichtlichsten ist, wenn du auslesen und Inkrementieren immer zusammen schreibst. Also: Auslesen eines Zeichens:

    char c = *file++;
    

    Danach steht der Lesezeiger ein Zeichen weiter auf dem nächsten Zeichen. Auslesen von 7 Zeichen: deine Schleife. Danach steht der Zeiger auf dem danach folgenden Zeichen. Das ist auch konsistent mit der üblichen Implementierung der Streamoperatoren, dass der gesamte gelesene Input konsumiert wird. Und wenn du die Schleife mal in eine Funktion packst, erwartest du ja auch nicht, dass du danach noch mal ein Zeichen lesen musst, um mit dem Auswerten vortfahren zu können.

    Bei der Gelegenheit solltest du auch nochmal überlegen, ob du den istream-Iterator überhaupt brauchst oder ob nicht die normalen Streamoperationen besser wären. Da gibt es dann auch keine Missverständnisse, wo gerade der Lesezeiger ist. Der Sinn der Streamiteratoren ist eigentlich vorwiegend, dass Algorithmen, die mit Iteratoren arbeiten, auch auf Streams operieren können.



  • das von ipsec finde ich einleuchtend.

    ich hab den stream iterator genommen, weil ich es einfacher fand, mit diesen die datei auszulesen.
    ich könnte ich auch ifstream::read benutzten (ich muss eigentlich mehr oder weniger blöcke von bekannter größe einlesen), aber so wie die ganzen beispiele dazu sind, muss ich da ganz schön mit cstrings rumhantieren, oder kann man die funktion auch mit c++ strings verwenden?
    und wenn ich ifstream::get benutzte, kommt das doch fast auf das gleiche wie die iterator variente hinaus, oder?
    eine andere möglichkeit wäre ja noch, sich einen eigenen iterator, wrapper (oder wie man es auch nennen mag) zu basteln, der dann genau auf dieses format abgestimmt ist, so dass dieser zum beispiel ein block auf einmal einliest, den zurückgiebt, so dass man diesen weiter bearbeiten kann.
    welchen weg würdet ihr nehmen, um eine datei einzulesen?



  • Du kannst den istream genau wie jeden anderen Stream (z.B. cout ) verwenden. Insbesondere funktionieren die Operatoren << und >> .



  • vario-500 schrieb:

    ich will das 'R' nicht mehrmals einlesen, ich will nur der Übersichtlichkeit halber im nächsten schritt wo ich das '_' einlese, erst ++file schreiben.

    Warum? Du schreibst ja auch nicht ++file, bevor Du das erste Zeichen einliest.


Log in to reply