Klassen aus Dateien in Vektor schreiben
-
Hi, habe daten aus einem vektor in eine txt-datei geschrieben und möchte jetz aus der datei den selben vektor wieder mit den daten der txt füllen, wie geht das am besten?
der vektor heißt kundenliste
ifstream input ("kundendaten.txt"); input.read ((char *) &kundenliste, sizeof (kundenliste)); }braucht ihr mehr code?
-
Wenn du die Daten analog geschrieben hast, kannst du dir das Einlesen sparen, dann steht in der Datei nur Schrott.
-
input.read ((char *) &kundenliste, sizeof (kundenliste)); }Wenn kundenliste ein std::vector ist, dann ist das in vielfacher Hinsicht falsch:
-sizeof eines vectors ist die Größe der Verwaltungsdaten, nicht des logischen Inhalts.
-Ebenso ist die Adresse eines Vectors die Größe der Verwaltungsdaten, nicht des Inhalts.
-Entsprechend überschreibt dein Versuch hier irgendwie die Verwaltungsdaten des Vectors, was zu totalem Müll führt.
-Woher soll der Vector eigentlich im Vorhinein wissen, wie groß er sein soll?Da dieser Versuch so extrem falsch ist, würde es mich nicht wundern, wenn du die Daten bereits falsch in deine Datei geschrieben hast. Zeig mal, wie du die Daten geschrieben hast. Diese Information ist sowieso nötig, wenn wir dir beim Lesen helfen sollen, denn das Serialisieren eines Vectors mit ist nicht trivial und könnte von dir auf vielerlei Weise versucht worden sein. Je nachdem, was du gemacht hast, sieht die Umkehrung dann anders aus.
-
Im Prinzip passiert alles genau wie ich es will, auch das in die datei schreiben 100% perfekt für mich und genau beabsichtigt. Wenn ich das Programm schließe sind die Kundendaten natürlich weg. Beim neustarten soll die Option "5" in der main diese kundendaten wieder herstellen, indem der vektor mit den Daten der Datei gefüllt wird.
#include <iostream> #include <vector> #include <string> #include <fstream> using namespace std; class verwaltung; class kunde { friend class verwaltung; private: int id; int pin; int cash; string stadt; string name; public: static int kundenid; kunde () { kundenid++; id = kundenid; cout << "Namen eingeben:" << endl; cin >> name; cout << "Stadt eingeben:" << endl; cin >> stadt; cout << "Kontostand eingeben:" << endl; cin >> cash; cout << "Kunde mit der ID " << id << " wurde erstellt" << endl; } void zeigekundendaten () { cout << "Kundenidentifikationsnummer: " << endl; cout << "Name: " << name << endl; cout << "Kontostand: " << cash << endl; cout << "Wohnort: " << stadt << endl; } void schreibedaten (ostream* x) { cout <<"Kundendaten von Kunden ID: " << id << " werden gesichert." << endl; *x << "Kundenidentifikationsnummer: " << endl; *x << "Name: " << name << endl; *x << "Wohnort: " << stadt << endl; *x << "Kontostand: " << cash << endl << endl; } }; class verwaltung { private: vector<kunde>kundenliste; public: void neuerkunde () { kunde neuerkunde; kundenliste.push_back (neuerkunde); } void size (){ cout << kundenliste.size(); } void suchekunde (string name) { int zaehler = 0; vector<kunde>:: iterator i; for (i=kundenliste.begin();i!=kundenliste.end();i++) { if (i->name==name) { cout << "gefunden: "; i->zeigekundendaten(); zaehler++; } if (zaehler==0) cout << "Es wurden keine Eintraege gefunden" << endl; } } void kundendatenspeichern () { vector<kunde>:: iterator i; ofstream output ("kundendaten.txt"); for (i=kundenliste.begin();i!=kundenliste.end();i++) { i->schreibedaten(&output); } output.close(); } }; int kunde::kundenid; int main() { kunde::kundenid = 0; char option; string name; verwaltung boss; do { cout << " Guten Tag, Boss." << endl; cout << "(1) Neuen Kunden anlegen" << endl; cout << "(2) Kunden suchen" << endl; cout << "(3) Kundenanzahl anzeigen" << endl; cout << "(4) Kunden speichern" << endl; cout << "(5) Kunden laden" << endl; cout << "(b) Programm beenden" << endl; cin >> option; if (option=='1') boss.neuerkunde(); else if (option=='2') { cout << "Namen eingeben: "; cin >> name; boss.suchekunde(name); } else if (option=='3') boss.size(); else if (option=='4') boss.kundendatenspeichern(); else if (option=='5') { ifstream input ("kundendaten.txt", ios::binary); input.read ((char *) kundenliste, sizeof (kundenliste)); } else cout << "Ungueltige eingabe" << endl; cout << endl; } while (option != 'b' ); }
-
also was ihr sucht ist glaube ich methode "kundendatenspeichern" von klasse verwaltung und methode "schreibedaten" von klasse kunde
-
Hast du den Code selbst geschrieben? Die beiden Teile passen überhaupt nicht zusammen. Das Rausschreiben ist extrem formatiert, es werden ja sogar redundante Beschreibungen der Kategorie bei jedem Datensatz mit rausgeschrieben. Aber dein Leseversuch ist ausgelegt auf unformatierte Rohdaten. Eines von beiden hast du nicht selber gemacht.
Was du brauchst ist eine passende Lesefunktion für deine Kundendaten. Ungefähr das, was du derzeit im Konstruktor machst*, bloß dass es in der Lage ist, die von dir ausgegebenen Daten zu lesen (also insbesondere muss es mit deinen Kategorien zurecht kommen). Dann liest du einfach umgekehrt ein, wie du geschrieben hast. Ganz ohne read oder binary.
Außerdem solltest du dir dringend mal ansehen, was Referenzen sind.
*: Wieso führt der Konstruktor einer Klasse eine interaktive Nutzerbefragung durch? Das hat da vom Design her nichts zu suchen!
-
ich würd jetzt sagen zeiger referenzen...ist doch alles call by reference was solls, aber dann gibts siche verbale ohrfeigen von jeder seite. Muss mir nochmal die Unterschiede geben. Eigentlich sind zeiger (dachte ich zumindest) die große stärke von c++ aber jeder rät immer zur referenz.
ist richtig, der "roh-datencode" ist ausm buch nachdem meine versuche es nicht gebracht haben.
ich verstehe was du meisnt aber nicht wie man es umsetzen könnte, da ich ja wahrscheinlich in c++ definieren muss, welche passagen aus der txt, zu welcher membervariablen gehören soll. kannst du mir bitte codefragmente schreiben auf die ich wahrscheinlich nicht kommen werde oder die mich auf die Idee bringen, wie man es umsetzen könnte?
-
fghfgh schrieb:
ich würd jetzt sagen zeiger referenzen...ist doch alles call by reference was solls, aber dann gibts siche verbale ohrfeigen von jeder seite. Muss mir nochmal die Unterschiede geben. Eigentlich sind zeiger (dachte ich zumindest) die große stärke von c++ aber jeder rät immer zur referenz.
Totaler Unsinn, wie kommst du da drauf?
ich verstehe was du meisnt aber nicht wie man es umsetzen könnte, da ich ja wahrscheinlich in c++ definieren muss, welche passagen aus der txt, zu welcher membervariablen gehören soll. kannst du mir bitte codefragmente schreiben auf die ich wahrscheinlich nicht kommen werde oder die mich auf die Idee bringen, wie man es umsetzen könnte?
Die erste Frage ist: Soll das Ausgabeformat so bleiben?
Derzeit gibst du so etwas aus:Kundenidentifikationsnummer: 21234 Name: Max Mustermann Wohnort: Hinterkuckucksheim Kontostand: 3324535 [nächster Datensatz]Kann man so machen. Man könnte auch:
21234 Max Mustermann Hinterkuckucksheim 3324535 [nächster Datensatz]Oder
21234 Max Mustermann Hinterkuckucksheim 3324535 [nächster Datensatz]oder
21234;Max Mustermann;Hinterkuckucksheim;3324535 [nächster Datensatz]oder Varianten davon. Vorteile: Leichter zu lesen (für einen Computer); deutlich kleinere Datei. Nachteile: Weniger flexibel, insbesondere was spätere Erweiterungen angeht; schlechter für Menschen lesbar.
Wenn du schon weißt, dass niemals Erweiterungen kommen werden, dann könnte man so ein Format zum Schreiben benutzen. Wenn du mit Erweiterungen rechnest, könnte man auch dein jetziges Format noch stärker darauf auslegen, damit zurecht zu kommen (wobei es derzeit schon ganz ok ist).
-
egal mit zeiger und referenz, lese ich mir nochmal durch.
sagee ich mal ich möchte mein ausgabeformat nicht ändern, wie mache ich meinem programm begreifbar, welche zeilen der txt datei es verwenden soll, um membervariablen zu füllen. zB zuerst soll der name einer instanz gefüllt werden. in der textdatei ist der name aber in zeile 2. Ich kenne mich da überhaupt nicht aus ich google das mal. aber wenn jemand ein gutes tut kennt bitte trotzdem posten.