Eine Strucktur mit fstreams speichern
-
Hallo,
ich hab mal eine Frage auf die ich bis jetzt keine richtige Antwort gefunden habe.
Und zwar:
Kann man, und wenn ja wie, Struckturen mit fstream in einer Datei speichern?
(Ausdrücklich ohne FILE*)Ein Beispielcode oder Prototyp wäre auch schön.
Danke schon mal an alle die sich den Kopf zerbrechen
-
Wenn man es nicht binär macht, muss man halt memberweise ein- oder auslesen.
struct MyStruct { int Count; double Decimal; };MyStruct Var; std::ofstream Out("file.txt"); Out << Var.Count << " " << Var.Decimal << std::endl; std::ifstream In("file.txt"); In >> Var.Count >> Var.Decimal >> Var.Address;Das Ganze kann man natürlich noch ausbauen, indem man z.B.
std::getline()verwendet. Oder man überlädt gleich die Streamoperatoren für die Struktur.Auf www.cplusplus.com findest du mehr Infos zu
std::fstream, da sollte sich auch einiges klären.
-
Soll das heißen das Folgendes nicht funktioniert?
#include <fstream>
struct bsp
{
char name[20];
int alter;
};void main()
{
fstream datei;
bsp obj;datei.open(ios_base::app | ios_base::binary);
datei<<obj<<endl;
datei.close();
}
Gibt es nicht so was wie eine OOP Variante von fread() und fwrite()?

-
Öhm nein.Das ist nicht wie in C# mit der XML-Serialisierung, hier muss man alles von Hand machen was auch meines Erachtens logisch ist.Weil woher soll der Compiler wissen, was wie geschrieben wird?;)
-
guest brain schrieb:
datei<<obj<<endl;
Gibt es nicht so was wie eine OOP Variante von fread() und fwrite()?

Im Prinzip schon. Nur das Format bleibt dem User (also Dir überlassen) - dafür schreibt man Code wie diesen:
struct bsp { std::string name; // erfordert #include <string> int alter; }; // bsp - Objekt ausgeben (erfordert #include <iostream>) std::ostream& operator<<( std::ostream& out, const bsp& x ) { return out << x.name << " " << x.alter; }dann wird Dein oben vorgesehener Aufruf möglich. Das Einlesen geht entsprechend mit std::istream& operator>>( ..
Gruß
Werner
-
Firefighter schrieb:
Öhm nein.Das ist nicht wie in C# mit der XML-Serialisierung, hier muss man alles von Hand machen was auch meines Erachtens logisch ist.Weil woher soll der Compiler wissen, was wie geschrieben wird?;)
Keine Ahnung woher der das wissen soll aber bei fwrite() weiß er's doch auch.
Wegen dem letzten BspCode, an der return Zeile meckert mein Kompiler
ofstream& operator<<(ofstream& out, const bsp& x ) { return out<<x.name<<" "<<x.alter; }Fehlermeldung:
43 D:\test\operatoren.cpp invalid initialization of reference of type 'std::ofstream&' from expression of type 'std::basic_ostream<char, std::char_traits<char> >'Kann mir mal jemand das decodieren?
-
guest brain schrieb:
ofstream& operator<<(ofstream& out, const bsp& x ) { return out<<x.name<<" "<<x.alter; }Fehlermeldung:
43 D:\test\operatoren.cpp invalid initialization of reference of type 'std::ofstream&' from expression of type 'std::basic_ostream<char, std::char_traits<char> >'Kann mir mal jemand das decodieren?
Ja - die Kunst besteht im richtigen Abschreiben - im meinem Posting steht kein 'f' zwischen 'o' und 'stream'

Der Compiler teilt dir mit, dass er aus einem ostream keinen ofstream machen kann - was völlig ok ist.Gruß
Werner
-
Ups da hab ich wohl nen fehler gemacht.
Danke. Geht das auch mit fstream?
-
...und wenn ich es richtig lese ist die Klasse ostream protected.

-
guest brain schrieb:
Ups da hab ich wohl nen fehler gemacht.
Danke. Geht das auch mit fstream?was soll mit fstream gehen ? ein Ausgabeoperator mit ofstream macht keinen Sinn ..
guest brain schrieb:
...und wenn ich es richtig lese ist die Klasse ostream protected.

Nein - die Klasse ist nicht protected - wo liest man das?
Nimm einfach Dein Programm von oben - lass einiges überflüssiges weg, füge den Ausgabeoperator, den ich Dir geschrieben habe, hinzu und Du bekommst:
#include <iostream> #include <fstream> #include <string> struct bsp { // ein Konstruktor wäre hier noch sinnvoll std::string name; // erfordert #include <string> int alter; }; // bsp - Objekt ausgeben (erfordert #include <iostream>) std::ostream& operator<<( std::ostream& out, const bsp& x ) { return out << x.name << " " << x.alter; } int main() { using namespace std; ofstream datei( "output.txt" ); bsp obj; datei<<obj<<endl; return 0; }.. und baue Dir noch einen Konstruktor für die struct.
Gruß
Werner
-
Das ist der Fehler den Dev-C++ aus gibt:
361 C:\Dev-Cpp\include\c++\3.4.2\ostream `std::basic_ostream<_CharT, _Traits>::basic_ostream() [with _CharT = char, _Traits = std::char_traits<char>]' is protected <-- Da steht protected
Und am liebsten würde ich es gern so machen damit ich nicht einen Stream für eingabe und einen für ausgabe definieren muss, daher fstream:
#include <iostream> #include <fstream> using namespace std; int main() { fstream datei; char text[51]; cout<<"Bitte Text eingeben: "<<endl; cin.get(text, 50); datei.open( "t.txt", ios_base::out | ios_base::app | ios_base::binary ); datei<<text; datei.close(); system("cls"); datei.open("t.txt",ios_base::in); for(int i = 0; !datei.eof(); i++) { if( i>50 ) { text[51] = '\0'; break;} datei.get(text[i]); } cout<<text<<endl;; system("PAUSE"); return 0; }Und wie in Zeile 16 würde ich das gerne mit einer Strucktur machen.
-
Was gefällt dir denn an den überladenen Operatoren nicht?
Bezüglich deines compilers würde ich dir raten mal einen neueren zu nehmen. Dev-C++ ist schon sehr alt und wird auch nicht mehr weiter entwickelt.
CodeBlocks mit MinGw ist hier eine gute Alternative (siehe FAQ).
Wenn du binär schreiben und lesen willst sind die operatoren << und >> aber eh fehl am Platz. Dafür gibt es dann die Stream-Memberfunktionen read und write.
Bei einer Klasse wäre es gut gleichlautende Memberfunktionen zu implementieren.
-
Kann vll endlich ma jmd den Thread-Titel ändern?

egal in was - Hauptsache, das Stru
cktur kommt weg ^^danke + bb
-
guest brain schrieb:
Das ist der Fehler den Dev-C++ aus gibt:
361 C:\Dev-Cpp\include\c++\3.4.2\ostream `std::basic_ostream<_CharT, _Traits>::basic_ostream() [with _CharT = char, _Traits = std::char_traits<char>]' is protected <-- Da steht protected
Dort (in Zeile 361 ?) wird versucht den Defaultkonstruktor von std::ostream aufzugerufen - den gibt es aber im C++-Standard gar nicht!? In dem Code, den ich gepostet habe, passiert das nirgendwo, also hat dieser Code, der den Compiler-Feher auslöst, nichts mit dem zu tun, was hier gepostet wurde !?
guest brain schrieb:
Und am liebsten würde ich es gern so machen damit ich nicht einen Stream für eingabe und einen für ausgabe definieren muss, daher fstream:
Es ist mir unklar, was das eine mit dem anderen zu tun hat - vielleicht weißt Du nicht, dass der fstream letztlich nichts anderes als ein ostream und ein istream ist.
Außerdem sind zwei Stream-Objekte - eines für Input und eines für Output viel einfacher zu handeln.Gruß
Werner