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