Frage zu Standard-Streams



  • Hallo Leute!

    Es gibt ja ofstream und ifstream. Ganz praktisch um direkt aus der Datei zu lesen (und schreiben).
    Gibt Es auch Streams die komplett im RAM liegen und mit denen ich genauso arbeiten kann?
    Soll heißen Daten aus der Datei lesen, in den Stream einfügen und dann den Stream bearbeiten.
    Also mit den std::stream-Klassen Datein bearbeiten, nur dass es eben die Quelle keine Datei sondern ein Speicherbereich war.
    Ich meine aber keinen stringstream, eher was für Binärdaten.

    Kennt sich da jemand aus?



  • Ich denke nicht, dass das wirklich Sinn macht.
    Du musst so, oder so wissen, welche Daten zueinander gehören. Das kann man ja nicht rausfinden, wenn man lediglich Bytes hat, die nacheinander aufgelistet sind.



  • Man muss immer zwischen den Stream und seinem Streambuffer unterscheiden!
    Es gibt im C++-Standard nur zwei Streams - ostream und istream. Alle anderen wie i/ofstream und stringstream sind Derivate - also von diesen beiden abgeleitet und ändern das Stream-Verhalten gar nicht!
    Ein Stream kann überhaupt keine Daten speichern - nicht ein Zeichen! er 'liegt' also auch nirgendwo - dafür ist immer sein Streambuf zuständig. Ein ifstream ist z.B. ein istream unter dem ein std::basic_filebuf<> aufgehängt ist. Die Klasse ifstream dient nur dazu eine Hülle zu bilden in der sich ein istream und ein basic_filebuf<> befinden - mehr nicht.

    i/ostream sind dafür gemacht mit 'von Menschen lesbaren' Daten zu operieren. Für das Arbeiten mit Binärdaten bietet es sich an, einen eigenen Stream zu bauen, der dann von std::basic_ios abgeleitet ist. Etwa in der Weise:

    // ibinstream.h
    #pragma once
    #include <ios>
    #include <streambuf>
    
    class ibinstream : public std::basic_ios< char >
    {
    public:
        typedef std::basic_ios< char > base_type;
        explicit ibinstream( std::streambuf* sb = 0 )
            : base_type( sb )
        {}
    
        ibinstream& operator>>( int& x_ )
        {
            if( good() )
            {
                int x;
                if( rdbuf()->sgetn( reinterpret_cast< char* >( &x ), sizeof(x) ) == sizeof(x) )
                    x_ = x;
                else
                    setstate( std::ios_base::failbit | std::ios_base::eofbit );
            }
            return *this;
        }
    
        // --- fuer Manipulatoren ohne Parameter
    	ibinstream& operator>>( ibinstream&(*_F)(ibinstream&) )
    		{return( (*_F)(*this) );};
    
    };
    

    Diese einfache Implementierung liest binär einen 'int' so wie er im Speicher liegt.

    Einen Stream muss man immer mit einem Streambuffer verbinden. Für einen Streambuffer im Ram gibt es std::basic_stringbuf<>. Diesen kann man zuvor z.B. aus einer Datei befüllen und anschließend die Daten binär auslesen.

    #include "ibinstream.h"
    #include <cassert>
    #include <fstream>
    #include <iostream>
    #include <sstream>      // basic_stringbuf
    
    int main()
    {
        using namespace std;
        basic_stringbuf< char > sb;
        ifstream file( "input.txt", ios_base::binary );
        file >> &sb;        // ganze Datei in Buffer schreiben
    
        ibinstream in( &sb );   // Binärstream über den Buffer 'stülpen'
        int i;
        if( in >> i ) 
            cout << i << " richtig gelesen " << endl;
        return 0;
    }
    

    Alternativ kann man natürlich auch den Streambuffer des ifstreams verwenden und den Binär-Stream direkt aus der Datei lesen lassen. Also:

    ifstream file( "input.txt", ios_base::binary );
        ibinstream in( file.rdbuf() );   // Binärstream über den File-Buffer 'stülpen'
    

    Gruß
    Werner



  • Boah! Genau was ich gesucht habe!
    Wo lernt man denn das ganze std::iostream-Zeug?



  • Blaze schrieb:

    Boah! Genau was ich gesucht habe!
    Wo lernt man denn das ganze std::iostream-Zeug?

    Standard C++ Iostreams and Locales: Advanced Programmer's Guide and Reference
    von Klaus Kreft, Angelika Langer
    # Verlag: Addison-Wesley Longman, Amsterdam (31. Januar 2000)
    # Sprache: Englisch
    # ISBN-10: 0201183951
    # ISBN-13: 978-0201183955

    .. plus jahrelange C++-Praxis 😉

    Gruß
    Werner


Anmelden zum Antworten