Anfängerfrage
-
Hallo
Ich fange gerade an mit C++ programieren. Hab jetzt ein Problem wie ich etwas in eine Datei speichere.
Das Problem:
Ich habe 2 Klassen. Klasse Person und Klasse Buch. Das ganze gehört zu einem Programm Telefonbuch.
In der Klasse Person werden alle Persenenbezogenen Daten wie Name, Vorname und Telefonnummer eingegeben. In der Klasse Buch sollen alle Personen zusammengefasst werden.
In der Klasse Buch ist auch einen Funktion zum Speichern der Daten in eine Datei.
Das Problem ist jetzt wie bekomm ich die Personen in die Datei.
Das erstellen einer Datei ist kein Problem. Ich will die Datein Zeilenweise in die Datei schreiben.
Ich denke das geht ja nur das man eine Schleife jat die bis zu der Anzahl der Personen durchgeht und dann die Personen reinschreibt....
ofstream raus;
ifstream rein;
...
bool sichern(char *pfad)
{
raus.open(pfad,ios::out);
if (!raus)
{
cout<<"Dateianlegen fehlgeschlagen";
return false;
}
else
{
cout<<"Datei erstellt";
for (size_t i =0;i<anz;i++) Weiß nicht ob es so richtig ist
raus<<buch()<<"\n"; bis jetzt funktioniert es so nicht
raus.close(); ich weiß auch nicht mehr weiter
return true; finde in keinem Buch Hilfe
}
}bool lesen(char *pfad)
{
...
{
...
else
...
while(!rein.eof())
rein<<buch()<<endl;
rein.close();
return true;
}
}Hoffe mir kann jemand weiterhelfen und das die Informationen reichen. Wenn nicht dann schreibt.
Mfg Carsten
-
Schreib ei einfach ne Funktion, die die Werte von Buch in die Datei schreibt, z.b.
Datei << Name << Alter << Telefonnummer;Dann kannste lesen:
Datei >> Name;
Datei >> Alter;
Datei >> Telefonnummer;Das muss halt Stadnardisiert sein, du kannst nicht nen string reinschreiben und an der Position ein int rausholen wollen.
-
Danke für die schnelle Antwort.
Ich hab das gleich mal so ausprobiert. Aber es funktioniert immernoch nicht.
Ich hab das jetzt so geschrieben:
raus<<p.name<<p.vorname<<p.tel;
p wurde in Buch im PRIVATE so deklariert:
person **p;
In der Klasse Person wurde alles so deklariert:
Im Private.char *name;
char *vorname;
char **tel;In Tel können mehrere Telefonummern stehen.
Weiß da nicht mehr weiter.
Mfg Carsten
-
Mach das doch in etwa so: (Ungetestet, als Denkanstoss)
class Person { private: std::string name; std::string telnummer; public: // Konstruktor, etc. void setName(const std::string& n) { name = n; } void setTelnummer(const std::string& tn { telnummer = t; } std::string getName() { return name; } std::string getTelnummer() { return telnummer; } }; class Buch { private: // Deine Private-Sachen const unsigned ELEMENTE; Person v[ELEMENTE]; public: // Ctor, etc. alles schön initalisieren void read(const std::string& fn); } void Buch::read(const std::string& fn) { std::ostream outfile(fn.c_str()); int i = 0; while(i++ < ELEMENTE) outfile << v[i].getName() << v[i].getTelnummer() << std::endl; }
Caipi
-
Danke für deine Antwort.
Das Problem ist das die ganzen Variablen als Zeiger bleiben müssen.
Das gehört so zur Aufgabenstellung.Hab jetzt mal versucht mit dem this zeiger was zu machen.
rein<<(*this)[i].getname<<(*this)[i].getvorname
Aber da kommt jetzt ein Fehler ...NullException...
Hoffe mir kann dazu nochmal jemand helfen.
Danke im vorraus
Carsten
-
Schreib halt die Funktionen um, so das sie einen char-Zeiger zurückgeben anstatt des std::strings: (Beispiel)
void Person::setName(const char* n) { memcpy(name, n, MAX_SIZE_FOR_NAME); } // set-Example char* Person::getName() { return name; } // get-Example
Danach ungefähr so aufrufen:
// In void Buch::read() outfile << v[i].getName() << std::endl; outfile << v[i].getTelnummer() << std::endl;
Caipi
-
Danke für die Hilfe die ich bis jetzt bekommen habe. Nur leider hat sie mir bis jetzt nicht genützt, weil es leider mit der Aufgabenstellung die ich habe nicht zusammenpasst.
Wenn sich jemand mal die Zeit nehemen würde sich mein Programm mal ansehen könnte und mir mal evtl sagt was da noch falsch ist mit dem schreiben in die Datei. Weil mein Problem ist jetzt das er die Namen reinschreibt aber die dazugehörigen Telefon nummern nicht. Die gibt er mir komischer weise wieder auf den Bildschirm aus.
Ich habe in meinem Programm auch ein Menü drin. In den Menüpunkten 1 - 1.4 soll er die ganzen Funktionen aus der Klasse Person testen. In dem Menüpunkt 1 soll er nur eine Person anlegen und dann können anahnd dieser Person die Funktionen unter 1.1 - 1.4 getestet werden. Ich komme nur nicht von den Menüpunkten 1.1 - 1.4 auf die angelegte Person drauf.
Den Code würde ich demjenigen der sich das mal ansehen würde per Mail schicken, weil es sind ca 750 Zeilen und das wäre hier zu viel Text
Mfg Carsten
-
Hab hier mal den gesamten Quelltext.
#include <iostream> #include <iomanip> #include <fstream> using namespace std; class person; ostream &operator<<(ostream &cout, person &p); istream &operator>>(istream &cin, person &p); //Klasse Person class person { //Familienname char *name; //Vorname char *vorname; //Zeiger auf Vektor von Zeigern auf Telefonnummern char **tel; //Anzahl der Telefonnummern der Person unsigned int at; public: //Defaultkonstruktor, Eingabe über cin person() : name (0), vorname (0), tel (0), at (0) { cin>>*this; }; //Überladener Konstruktor person(char *pname, char *pvorname = 0) : tel (0), at (0) { //neues Feld anlegen --> mit länge des Namens + 1 name = new char [strlen(pname)+1]; //Kopiert pname in name strcpy (name, pname); if (pvorname == 0) vorname = 0; else { //neues Feld anlegen --> mit länge des Vornames + 1 vorname = new char [strlen(pvorname)+1]; //Kopiert pvorname in vorname strcpy (vorname, pvorname); } if (strcmp (name, "Ende")) { cout<<"\232berladener Konstruktor"<<endl; cout<<"-----------------------"<<endl; //Kontrollausgabe der Variablen cout<<'\n'; cout<<"Name : "<<name<<endl; if (vorname) cout<<"Vorname : "<<vorname<<endl; } }; //Überladener Konstruktor, optional Telefonnummer person(char *pname, char *pvorname, char *ptelnr) { //neues Feld anlegen --> mit länge des Namens + 1 name = new char [strlen(pname)+1]; //Kopiert pname in name strcpy (name, pname); //neues Feld anlegen --> mit länge des Vornames + 1 vorname = new char [strlen(pvorname)+1]; //Kopiert pvorname in vorname strcpy(vorname, pvorname); at = 1; tel = new char * [1]; //neues Feld anlegen --> mit länge der Telefonnummer + 1 tel [0] = new char[strlen(ptelnr)+1]; strcpy(tel[0],ptelnr); cout<<"\232berladener Konstruktor, optional Telefonnummer"<<endl; cout<<"-----------------------------------------------"<<endl; //Kontrollausgabe der Variablen cout<<'\n'; cout<<"Name : "<<name<<endl; cout<<"Vorname : "<<vorname<<endl; if(at) cout<<"Telnr : "<<tel[0]<<endl; }; //Kopierkonstruktor person(person &r) : at (r.at) { //neues Feld anlegen --> mit länge des Namens + 1 name = new char [strlen(r.name)+1]; //Kopiert name in name strcpy (name, r.name); //neues Feld anlegen --> mit länge des Vornames + 1 if (r.vorname) { vorname = new char [strlen(r.vorname)+1]; //Kopiert vorname in vorname strcpy(vorname, r.vorname); } else vorname = 0; if (at == 0) tel = 0; else { tel = new char * [at]; for (size_t i = 0; i < at; i++) { tel[i] = new char [strlen (r.tel[i])+1]; strcpy (tel[i], r.tel[i]); } } }; //Überladener Zuweisungsoperator person &operator=(person &r) { if (this != &r) { //alter Inhalt wird gelöscht ... Destruktor delete [] name; if (vorname) delete [] vorname; for(size_t i = 0; i < at; i++) { delete [] tel[i]; } delete [] tel; name = 0; vorname = 0; tel = 0; at = 0; //wird mit neuem Inhalt belegt ... Kopierkonstruktor //neues Feld anlegen --> mit länge des Namens + 1 name = new char [strlen(r.name)+1]; //Kopiert pname in name strcpy (name, r.name); //neues Feld anlegen --> mit länge des Vornames + 1 if (r.vorname) { vorname = new char [strlen(r.vorname)+1]; //Kopiert pvorname in vorname strcpy(vorname, r.vorname); } else vorname = 0; at = r.at; if (at == 0) tel = 0; else { tel = new char * [at]; for (size_t i = 0; i < at; i++) { tel[i] = new char [strlen (r.tel[i])+1]; strcpy (tel[i], r.tel[i]); } } } return *this; }; //Ersetzen der Telefonnummer tel[i] durch telnr bool operator()(unsigned int i, char *telnr) { if (i >= at) return false; delete [] tel[i]; tel[i] = new char [strlen(telnr)+1]; strcpy (tel[i],telnr); return true; } //Destruktor --> Speicherbereiche der Objekte werden freigegeben und auf 0 gesetzt ~person() { //alle Felder werden gelöscht (zerstört) delete [] name; if (vorname) delete [] vorname; for(size_t i = 0; i < at; i++) { delete [] tel[i]; } delete [] tel; //Name, Vorname, Telefonnummer und die Anzahl werden auf 0 gesetzt name = 0; vorname = 0; tel = 0; at = 0; }; //Zeiger auf Name als Rückgabewert char *getname() { return this->name; }; //Zeiger auf Vorname als Rückgabewert char *getvorname() { return this->vorname; }; //Anzahl Telefonnummern der Person unsigned int getat() { return this->at; }; //Kopie weiterer Telefonnummer *telnr hinzufügen void operator+(char *telnr) { if (!tel) { tel = new char *[++at]; tel[0] = new char [strlen(telnr)+1]; strcpy (tel[0], telnr); return; } char **htel = new char *[++at]; for (size_t i = 0; i < at-1; i++) htel[i] = tel[i]; htel [at-1] = new char [strlen(telnr)+1]; strcpy (htel [at-1], telnr); delete [] tel; tel = htel; } //Telefonnummer mit Index i löschen bool operator-(unsigned int i) { if (i < at) { char **htel = new char *[at-1]; for (size_t k = 0; k < i; k++) htel[k] = tel[k]; delete [] tel[i]; tel[i] = 0; for (size_t k = i+1; k < at; k++) htel[k-1] = tel[k]; delete [] tel; tel = htel; at--; return true; } else { cout<<"Index ist ung\201ltig!"<<endl; return false; } } //Ausgabe Telefonnummer mit Index i bool operator+(unsigned int i) { if (i < at) { cout<<i+1<<". Tel : "<<tel[i]<<endl; return true; } cout<<"Index ist ung\201ltig!"<<endl; return false; } //Löschen aller Telefonnummern der Person void operator-() { cout<<"Es werden alle Telefonnummern der Person gel\224scht!"<<endl; for(size_t i = 0; i < at; i++) { delete [] tel[i]; } delete [] tel; tel = 0; at = 0; } //Alle Telefonnummern der Person ausgeben void operator+() { for (size_t i = 0; i < at; i++) cout<<" "<<i+1<<". Tel : "<<tel[i]<<endl; }; //Indexoperator überladen (Telefonnr. i) char* &operator[](unsigned int i) { static char* dummy; char* *res = &dummy; if(i < at) res = tel + i; else { cout<<"Index ung\201ltig!"<<endl; } return *res; } }; //Ausgabe person p über cout ostream &operator<<(ostream &cout, person &p) { cout<<" Name : "<<p.getname()<<endl; cout<<" Vorname : "<<p.getvorname()<<endl; //Aufruf des operators alle Telefonnummern der Person ausgeben +p; cout<<'\n'; return cout; } //Eingabe person p über cin istream &operator>>(istream &cin, person &p) { char ename [15], evorname [15], etelnr [12]; cout<<"Bitte geben Sie den Namen ein: "; //Einlesen des Names cin>>ename; cout<<'\n'; cin.clear (); cin.ignore (INT_MAX, '\n'); cout<<"Bitte geben Sie den Vornamen ein: "; //Einlesen des Vornamens cin>>evorname; cout<<'\n'; cin.clear (); cin.ignore (INT_MAX, '\n'); //Aufruf des überladenen Konstruktors person neu(ename, evorname); cout<<'\n'; cout<<"Bei keiner Eingabe der Telefonnumer # - Taste dr\201cken"<<endl; cout<<'\n'; while(1) { cout<<"Bitte geben Sie die Telefonnummer ein: "; //Einlesen der Telefonnummer cin>>etelnr; if (etelnr[0] == '#') break; //Aufruf des Operators Kopie weiterer Telefonnummer *telnr hinzufügen neu+etelnr; cout<<'\n'; } //Aufruf des überladenen Zuweisungsoperators p = neu; cin.clear (); cin.ignore (INT_MAX, '\n'); return cin; } class buch; int cmp(const void *a, const void *b); ostream &operator<<(ostream &cout, buch &b); istream &operator>>(istream &cin, buch &b); ofstream raus; ifstream rein; class buch { //Zeiger auf Vektor von Zeigern auf person person **p; //Anzahl der Vektorelemente unsigned int anz; public: //Defaultkonstruktor buch buch() : p (0), anz (0) {}; //Kopierkonstruktor buch(buch &b) : anz (b.anz) { if (anz == 0) p = 0; else { p = new person *[anz]; for (size_t i = 0; i < anz; i++) p[i] = new person (b[i]); } } //Überladen des Zuweisungsoperators buch &operator=(buch &b) { if (this != &b) { //alter Inhalt wird gelöscht ... Destruktor for (size_t i = 0; i < anz; i++) { delete p[i]; p[i] = 0; } delete [] p; anz = 0; p = 0; //wird mit neuem Inhalt belegt .. Kopierkonstruktor if (anz == 0) p = 0; else { p = new person *[anz]; for (unsigned int i = 0; i < anz; i++) p[i] = new person (b[i]); } } return *this; } //Destruktor buch --> Speicherbereiche der Objekte werden freigegeben und auf 0 gesetzt ~buch() { for (size_t i = 0; i < anz; i++) { delete p[i]; p[i] = 0; } delete [] p; anz = 0; p = 0; } //Kopie der Person *p hinzufügen buch &operator+(person *ph) { if (anz) { person **hp = new person *[anz+1]; for (size_t i = 0; i < anz; i++) hp[i] = p[i]; hp[anz] = new person (*ph); delete [] p; p = hp; anz++; } else { anz = 1; p = new person *[1]; p[0] = new person (*ph); } return *this; } //Person mit Index i löschen bool operator-(unsigned int i) { if (i < anz) { person **hp = new person *[anz-1]; for (size_t j = 0; j < i; j++) hp[j] = p[j]; for (size_t j = i+1; j < anz; j++) hp[j-1] = p[j]; delete p[i]; p = hp; anz--; cout<<"Person erfolgreich gel\224scht!"<<endl; return true; } else { cout<<"Index ist ung\201ltig!"<<endl; return false; } } //Ausgabe Person mit Index i mit allen Telefonnummern über cout bool operator+(unsigned int i) { if (i < anz) { cout<<(*this)[i]; return true; } else { cout<<"Index ist ung\201ltig!"<<endl; return false; } } //Alle Personen löschen void operator-() { cout<<"Es werden alle Personen aus dem Buch gel\224scht!"<<endl; for (size_t i = 0; i < anz; i++) { delete p[i]; p[i] = 0; } if (anz) delete [] p; p = 0; anz = 0; } //Alle Personen mit ihren Telefonnummern über cout ausgeben void operator+() { for (size_t i = 0; i < anz; i++) cout<<i+1<<(*this)[i]; } ///Indexoperator überladen person &operator[](unsigned int i) { if (i < anz) return *p[i]; else { cout<<"Index ist ung\201ltig!"<<endl; static person *h = new person ("Index", "un\201ltig"); return *h; } } //Objekt vom Typ buch in sequentieller Datei pfad sichern bool sichern(char *pfad) { raus.open(pfad,ios::out); if (!raus) { cout<<"Datei konnte nicht ge\224ffnet werden!"<<endl; return false; } else { cout<<"Datei erstellt"<<endl; for (size_t i = 0; i < anz; i++) raus<<(*this)[i]; raus.close(); return true; } } //Objekt vom Typ buch aus sequentieller pfad Datei lesen bool lesen(char *pfad) { rein.open(pfad,ios::in); if (!rein) { cout<<"Ausgabedatei konnte nicht ge\224ffnet werden!"<<endl; return false; } else { cout<<"Ausgabedatei ge\224ffnet"<<endl; int i = 0; while(!rein.eof()) { rein>>(*this)[i]; i++; } rein.close(); return true; } } //Sortieren von p[i] aufsteigend nach Name void sort() { qsort(p, anz, sizeof(person *), cmp); } }; //Funktion die qsort benötigt int cmp(const void *a, const void *b) { person *ha =*(person **)a; person *hb =*(person **)b; return strcmp(ha->getname(), hb->getname()); } //Ausgabe aller Personen ostream &operator<<(ostream &cout, buch &b) { +b; return cout; } //Eingabe aller Personen istream &operator>>(istream &cin, buch &b) { char ename [15], evorname [15], etelnr [12]; cout<<"Bitte geben Sie den Namen ein: "; //Einlesen des Names cin>>ename; cout<<'\n'; cin.clear (); cin.ignore (INT_MAX, '\n'); if (strcmp (ename, "Ende")) { cout<<"Bitte geben Sie den Vornamen ein: "; //Einlesen des Vornamens cin>>evorname; cout<<'\n'; cin.clear (); cin.ignore (INT_MAX, '\n'); //buch neu(ename, evorname); cout<<'\n'; cout<<"Bei keiner Eingabe der Telefonnumer # - Taste dr\201cken"<<endl; cout<<'\n'; while(1) { cout<<"Bitte geben Sie die Telefonnummer ein: "; //Einlesen der Telefonnummer cin>>etelnr; if (etelnr[0] == '#') break; //neu+etelnr; cout<<'\n'; } //b = neu; } else { //buch neu (ename); //b = neu; } cin.clear (); cin.ignore (INT_MAX, '\n'); return cin; } void main () { int eingabe; bool nochmal = true; buch *b = new buch(); while (nochmal) { //Auswahlprogramm system ("cls"); cout<<"\t\t\t\t============="<<endl; cout<<"\t\t\t\tPersonendaten"<<endl; cout<<"\t\t\t\t============="<<'\n'<<endl; cout<<"\t\t(1) Eingabe der Person"<<endl; cout<<"\t\t(11) Tel Nr. mit Index l\224schen"<<endl; cout<<"\t\t(12) Ausgabe Tel Nr. mit Index"<<endl; cout<<"\t\t(13) L\224schen aller Tel Nr. der Person"<<endl; cout<<"\t\t(14) Ausgabe der Person"<<endl; cout<<"\t\t(2) Eingabe mehrerer Personen"<<endl; cout<<"\t\t(21) Person mit Index l\224schen"<<endl; cout<<"\t\t(22) Ausgabe Person mit Index und aller Tel Nr."<<endl; cout<<"\t\t(23) Alle Personen l\224schen"<<endl; cout<<"\t\t(24) Ausgabe aller Personen"<<endl; cout<<"\t\t(3) Speichern in Datei"<<endl; cout<<"\t\t(4) Lesen aus Datei"<<endl; cout<<"\t\t(0) Programmende"<<endl; cout<<"\t\t Auswahl: "; cin>>eingabe; switch (eingabe) { //Programmende case 0 : { system ("cls"); nochmal = false; break; } //Eine Person eingeben case 1 : { system ("cls"); person *n = new person (); *b+n; delete n; break; } //Telefonummer mit Index löschen case 11 : { system ("cls"); int i; cout<<"Index 0 = Anfang"<<endl; cout<<"Geben Sie den Index der zu l\224schenden Tel Nr. an: "; cin>>i; //n->operator -(i); cin.get(); cin.ignore (INT_MAX, '\n'); break; } //Ausgabe Telefonummer mit Index case 12 : { system ("cls"); int i; cout<<"Index 0 = Anfang"<<endl; cout<<"Geben Sie den Index der anzuzeigenden Tel Nr. an: "; cin>>i; //n->operator +(i); cin.get(); cin.ignore (INT_MAX, '\n'); break; } //Löschen aller Telefonnummern der Person case 13 : { system ("cls"); //-*n; cin.get(); cin.ignore (INT_MAX, '\n'); break; } //Ausgabe der Person case 14 : { system ("cls"); //cout<<*n; cin.get(); cin.ignore (INT_MAX, '\n'); break; } //Mehrere Personen eingeben case 2 : { system ("cls"); while (1) { person *n1 = new person (); if (strcmp (n1->getname(), "Ende")== 0) break; *b+n1; delete n1; } b->sort(); break; } //Person mit Index löschen case 21 : { system ("cls"); int i; cout<<"Index 0 = Anfang"<<endl; cout<<"Geben Sie den Index der zu l\224schenden Person an: "; cin>>i; b->operator -(i); cin.get(); cin.ignore (INT_MAX, '\n'); break; } //Ausgabe einer Person mit Index und Tel Nr. case 22 : { system ("cls"); int i; cout<<"Index 0 = Anfang"<<endl; cout<<"Geben Sie den Index der auszugebenden Person an: "; cin>>i; b->operator +(i); cin.get(); cin.ignore (INT_MAX, '\n'); break; } //Alle Personen löschen case 23 : { system ("cls"); -*b; cin.get (); cin.ignore (INT_MAX, '\n'); system ("cls"); cout<<"\n\n\n\n\n\n\n\n\n\t\t\t Keine Daten vorhanden"<<endl; cin.get (); cin.ignore (INT_MAX, '\n'); break; } //Alle Personen ausgeben case 24 : { system ("cls"); cout<<*b; cin.get (); cin.ignore (INT_MAX, '\n'); break; } //Speichern in Datei case 3 : { system ("cls"); cout<<"Geben Sie einen Pfad zum sichern an: "; char pfad[20]; cin>>pfad; cout<<*b; b->sichern(pfad); cin.get(); cin.ignore (INT_MAX, '\n'); break; } //Lesen aus Datei case 4 : { system ("cls"); cout<<"Geben Sie die zu \224ffnende Datei ein: "; char pfad[20]; cin>>pfad; b->lesen(pfad); break; } default : { system ("cls"); cout<<"\n\n\n\n\n\n\n\n\n\t\t\tDiesen Men\201punkt gibt es nicht!"<<endl; cin.get (); cin.ignore (INT_MAX, '\n'); } } } };