inhalt eines struct speichern
-
Jo hi,
wie der titel schon ahnen lässt, möchte ich eine struktur in eine datei speichern und wieder auslesen,..
mein problem ist das fwrite nur einen pointer akzeptiert,..
mein struct ist aber kein pointer,..meinen source habe ich leider gerade nicht hier aber heißt das ich eine typenkonvertierung á la:
char *buffer=&mein_struct;machen muss?
(fragen koscht jo nüx)
seid gegrüßt;
-
Dein struct ist kein Pointer - aber du kannst ja die Adresse des structs nehmen (und die ist ein Pointer):
fwrite(&mein_struct,sizeof(mein_struct),1,datei);PS: Wir sind hier im C++ Forum, also empfehle ich mal std::fstreams anstelle des fwrite().
-
Genau das habe ich gemacht,..
resultat=>der inhalt der datei ist 0byte groß.
da das speichern und das lesen inerhalb einens programm ablaufes aber kein problem ist, schätze ich (achtung vermutung) das der höchstens die adresse aber nicht den inhalt speichert, daher die frage zur konvertierung,...
ja über fstream habe ich auch schon nachgedacht,..grüüße;
-
Außerdem würde ich Dir raten, es NICHT so zu machen.
Das ist zwar jetzt erst einmal bequem (und funktioniert wahrscheinlich auch erstmal), da aber nicht festgelegt ist, wie ein Compiler ein struct im Speicher (und damit dann auch in Deiner Datei) ablegt, erhältst Du ein hochgradig plattform- und Compiler-spezifisches Format.
... mit der hohen Chance, dass Du es später (andere Compilerversion oder -parameter; anderes Betriebssystem, ...) nicht mehr lesen kannst und wenig Chancen hast, es zu "reparieren".Außerdem wirst Du nur wenig von dem Zeug "per Auge debuggen" können. WENN also mal was nicht so funktioniert, stehst Du vor ziemlicher fieser Arbeit.
Deswegen mein Standard-Vorschlag:
- operator<<() und operator>>() überladen,
- Elementweise lesbar ablegen und
- ofstream, ifstream verwenden.zeusosc schrieb:
...schätze ich (achtung vermutung) das der höchstens die adresse aber nicht den inhalt speichert, ...
Aber auch die Adresse hätte mehr als 0Byte.

Ich schätze eher, dass Du
- gar nicht bis zum fwrite() gekommen bist oder
- das fclose() vergessen hast oder
während des Programmlaufes VOR erreichen des fclose() nachgesehen hast oder
- das File nicht zum Binärzugriff geöffnet hast (Flag b).Gruß,
Simon2.
-
Aber auch die Adresse hätte mehr als 0Byte.

Ich schätze eher, dass Du
- gar nicht bis zum fwrite() gekommen bist oder
- das fclose() vergessen hast oder
während des Programmlaufes VOR erreichen des fclose() nachgesehen hast oder
- das File nicht zum Binärzugriff geöffnet hast (Flag b).ich habe extra noch eine seperate routine geschrieben, die nach dem speichern, die daten mit extra neuem öffnen der dateien lädt und vergleicht,.. und diese sagte mir das alles ok ist,...
das compiler spezifisch die struct verwaltet werden ist *****, aber jetzt extra dafür ein daten writer/parser zu schribseln, gerade was die komplexität des structs betrifft, ist gegenüber dem eigendlichen programm evtl. zu aufwändig,...
gibts alternativen?grüüüße und dank;
-
Ja, innerhalb des selben Programms sind die Daten noch kompatibel. Aber wenn du dein struct speicherst, das Programm mit anderen Einstellungen neu compilierst und dann die Daten einliest, kommt womöglich nur Müll heraus.
@Simon: Der Zugriffsmodus (binär/text) hat aber keinen Einfluß darauf, ob fwrite() erfolgreich ist

-
zeusosc schrieb:
...
ich habe extra noch eine seperate routine geschrieben, die nach dem speichern, die daten mit extra neuem öffnen der dateien lädt und vergleicht,..Sorry, aber das sichert Dich eigentlich höchstens gegen eine fehlerhafte Implementation von fwrite() ab und sonst gegen gar nichts.
Mein Einwand bezog sich aber nicht darauf, sondern darauf, dass Du jetzt Files schreibst und sie
- nicht mehr lesen kannst, wenn Du im Release-Modus compilierst oder
- Deinem Kumpel schickst, der sie mit seinem Programm (das er z.B. mit anderen Compile-Parametern erstellt hat) nicht lesen kann.
- Oder Du willst in 2 Jahren diese Daten nochmal lesen und inzwischen hast Du eine neue Compilerversion installiert.Alternativen habe ich keine ... "quick&dirty" ist eben nicht nur "quick".

Letztlich ist die Aufgabe aber gar nicht so aufwendig (könnte man fast schon einen Generator für schreiben):struct myStruct { TypA a; TypB b; }; ostream& operator<<(myStruct const& s, ostream& ost) { return ost << a << " " << b << "\n"; } istream& operator>>(myStruct& s, istream& ist) { ist >> a; return ist >> b; }Damit kannst Du myStruct-Objekte über Konsole, File, Netz, ... (wofür immer Du einen ostream hast) ausgeben und einlesen.
Gruß,
Simon2.
-
CStoll schrieb:
...
@Simon: Der Zugriffsmodus (binär/text) hat aber keinen Einfluß darauf, ob fwrite() erfolgreich ist
Das behaupte ich auch nicht, aber kann es nicht trotzdem erfolgreich einen leeren String schreiben ? (z.B. weil das erste Byte des Structs 0 ist ? )
Gruß,
Simon2.
-
hier erstmal der teil von der speichern routine,...
FILE * temp_file; temp_file=fopen(temp_filename,"wb"); fwrite(&tf_data,sizeof(tf_data), sizeof(tf_data), temp_file); fclose(temp_file);und hier ist der struct:
typedef struct { temp_file_info tfi; temp_file_decks tfd; temp_file_stack tfs; }temp_file_data; typedef struct { long int temp_file_count_loops; char temp_file_filename[80]; long int temp_file_number_of_rounds; int temp_file_number_of_players; int temp_file_deck_index; }temp_file_info; typedef struct { cardtype temp_file_o_bigdeck[52]; cardtype temp_file_o_smalldeck[32]; cardtype temp_file_play_bdeck[52]; cardtype temp_file_play_sdeck[32]; cardtype temp_file_public_stack[5]; }temp_file_decks; typedef struct { stack_of_player temp_file_player[10]; played_stack temp_file_stochasticle_stack[10]; vector<played_hand> temp_file_stochasticle_hand_unsuited; vector<played_hand> temp_file_stochasticle_hand_suited; }temp_file_stack;und dass alles als iostream overloaden man man man,.. brauch ich wohl n bissl,..
najagut,. danke jungs,..
-
zeusosc schrieb:
...
... fwrite(&tf_data,sizeof(tf_data), sizeof(tf_data), temp_file); ......
Also das ist bestimmt nicht, was Du willst: Du hast vermutlich nicht "sizeof(tf_data)" viele Elemente (3. Parameter) in einem Array, oder ?
Du meinst bestimmt eher:fwrite(&tf_data,sizeof(tf_data), 1, temp_file);Siehe auch: http://www.cppreference.com/stdio/fwrite.html
Gruß,
Simon2.
-
Simon2 schrieb:
Das behaupte ich auch nicht, aber kann es nicht trotzdem erfolgreich einen leeren String schreiben ? (z.B. weil das erste Byte des Structs 0 ist ? )
fwrite() schreibt keine Strings, sondern Datenblocks - und auch im Textmodus haben da Null-Bytes keine Sonderbedeutung (das einzige Zeichen, das afaik im Textmodus anders behandelt wird als im Binärmodus, ist das NewLine).
@zeus: der Code sieht ja scheuslich aus - sowas kommt wohl heraus, wenn man C und C++ bunt durcheinanderwirft

-
CStoll schrieb:
Simon2 schrieb:
Das behaupte ich auch nicht, aber kann es nicht trotzdem erfolgreich einen leeren String schreiben ? (z.B. weil das erste Byte des Structs 0 ist ? )
fwrite() schreibt keine Strings, sondern Datenblocks - und auch im Textmodus haben da Null-Bytes keine Sonderbedeutung (das einzige Zeichen, das afaik im Textmodus anders behandelt wird als im Binärmodus, ist das NewLine)....
Aha !!
Ich kenne mich mit den Interna von fwrite() nicht aus und wusste das nicht, sondern bin davon ausgegangen, dass eine (vom Std erlaubte) fwrite-Implementierung für "Text-FILEs" auch 0-Terminierung berücksichtigen darf/kann/könnte/...
Wenn das aber so ist, ziehe ich mein Argument zurück (zumal im Code ja schon zu sehen ist, dass das 'b' angegeben ist) und behaupte das Gegenteil.

Gruß,
Simon2.
-
Hi simon2,
der 3te parameter bestimmt doch die blockgröße die auf "einmal" geschrieben werden soll, da das doch ein stream ist, sollte dieser dann den ganzen struct auf einmal schreiben oder nicht?? gruß
@CStoll:
hm naja,.. mein sinn lag nicht an schönheit,.. sondern nur daran das effektiv das gemacht wird was ich vorhatte,.. immerhin bin ich hier doch im c/c++ forum
,.. naja mal ehrlich hätte ja auch nicht gedacht das der source soooo lang wird,..
grüüße
-
Nein, der dritte Parameter bestimmt die Anzahl an Array-Elementen, die insgesamt geschrieben werden sollen (der zweite Parameter gibt die Größe eines Array-Elements an).
-
zeusosc schrieb:
Hi simon2,
der 3te parameter bestimmt doch die blockgröße die auf "einmal" geschrieben werden soll, da das doch ein stream ist, sollte dieser dann den ganzen struct auf einmal schreiben oder nicht?? gruß...
Und was gibt der 2. Parameter an ? :p

Deswegen hatte ich den link angegeben:
Simon2 schrieb:
Siehe auch: http://www.cppreference.com/stdio/fwrite.html
...Da steht's.
Gruß,
Simon2.