title image


Smiley Re: zeilen auslesen und löschen in einer txt
Hi



Hmjaaa.... naja. Ein bißchen was allgemeines:



Euer Lehrer hat euch vermutlich was von "Objektorientierung" erzählt - das ist in diesem Programm aber nicht so umgesetzt, wie es gedacht ist. Es werden ja einzelne Objekte für die Personen angelegt. Auf diesen Objekten kann man Methoden aufrufen. Z.B. die Methode "ausgeben".



Stell dir vor, du hättest zwei Kunden-Objekte anlegt:

Kunde kunde1();

Kunde kunde2();

Wenn man bei EINEM Objekt die Methode "ausgeben" aufruft, werden ALLE Personen ausgegeben. Das macht ja eigentlich keinen Sinn. Gewünscht wäre eigentlich, daß die Methode

kunde1.ausgeben();

wirklich NUR die Daten von kunde1 ausgibt:



void CKunde::ausgeben()

{

cout << " " << Vorname << " " << Nachname << " # " << endl;

}





Wenn man ALLE Kunden-Daten ausgeben wollte, würde man sich dafür eine eigene Klasse oder zumindest eine eigene Methode anlegen. Die Methoden und Eigenschaften (also z.B. auch "Dateiname") sollten sich IMMER nur auf das Objekt beziehen, auf dem sie aufgerufen werden. Andernfalls macht die ganze Objektorientierung ja keinen Sinn...



Wenn man dieses Konzept konsequent berücksichtigt, hat das aber noch Vorteile, die WEIT darüber hinausgehen, daß es "irgendwie logischer klingt". Man könnte z.B. die ausgeben()-Methode für Kunden definieren:



void CKunde::ausgeben(ostream &output) {

output << " " << Vorname << " " << Nachname << " # " << endl;

}



Nun kann man den Kunden da hin ausgeben, wo man will:



ofstream datei("datei.txt", ios::app);

kunde.ausgeben(datei); // Schreibt den Kunden in die Datei

kunde.ausgeben(cout); // Schreibt den Kunden auf den Bildschirm





Abgesehen davon kann man dann auch Polymorphie einsetzen (mal in Google oder Wikipedia nachlesen!). Das bedeutet, vereinfacht gesagt, daß man für alle CPerson-Objekte (egal ob Personal oder Kunde) die gleichen Methoden verwenden kann. Man brächte also z.B. nicht VIER Methoden

schreibeKundenInDatei

schreibePersonalInDatei

schreibeKundenAufBildschirm

schreibePersonalAufBildschirm

sondern nurnoch diese EINE Methode:



void alleAusgeben(vector<CPerson*> personen, ostream &output) {

for (int i=0; i
personen[i]->ausgeben(output);

}

}



Diese Methode könnte entweder Personal oder Kunden in eine Datei oder auf den Bildschirm schreiben. Es wird automatisch die richtige ausgeben()-Funktion aufgerufen, je nachdem, ob es Personal oder Kunden sind. Mit Operatorenüberladung wäre die Anwendung dann sogar noch einfacher...



However.



Genug gemotzt ;-)



Ich habe festgestellt, daß man die lies-Funktion garnicht unbedingt braucht, weil char[]s in diesem Fall genauso behandelt werden, wie 'string's. Hier mal dein Code mit einer Funktion "verwaltung", die im Moment nicht viel macht, aber als Basis für die notwendigen Erweiterungen dienen könnte. Kommentare und Änderungen sind mit XXX markiert.





#include <iostream>

#include <stdlib.h>

#include <fstream>

#include <string.h>

#include <stdio.h>

#include <vector>



using namespace std;





// ********** Basisklasse CPerson *************************

class CPerson

{

protected:

char Vorname[30];

char Nachname[30];

char Dateiname[30];

public:

void eingeben();

void ausgeben();

void suchen();

};



// ********** Abgeleitete Klasse CPersonal ****************

class CPersonal : public CPerson

{

private:

int PersNr;

public:

void eingeben();

void speichern();

CPersonal(char*, char*, int); // XXX Hier haben die Sternchen * gefehlt

CPersonal(); // XXX Den alten Konstruktor gibt's immernoch

//void lies(ifstream&, char*);// XXX Das nicht hierhin



void gibMichAus(); // XXX siehe Kommentare im Post

};











// ********** Methoden der Basisklasse CPerson ************

void CPerson::eingeben()

{

cout<<"Vorname = ";

cin>>Vorname;

cout<<"Nachname = ";

cin>>Nachname;

}



void CPerson::ausgeben()

{

char zeichen;

ifstream datei;

//system("clear");

datei.open(Dateiname);

if(!datei)

cout<<"Fehler";

else

{

cout<<"Personaldatei\n";

while(!datei.eof())

{

zeichen=datei.get();

if(zeichen=='#')

cout<<endl;

else

cout.put(zeichen);

}

datei.close();

}

//getch();

}



void CPerson::suchen()

{

char suchname[30],zeichenkette[30];

int i=0;

bool vorhanden=false;

ifstream datei;

cout<<"Suchname = ";

cin>>suchname;

datei.open(Dateiname);

while(!datei.eof())

{

zeichenkette[i]=datei.get();

if (zeichenkette[i]!=' ')

i++;

else

{

zeichenkette[i]='\0';

if(strcmp(zeichenkette,suchname)==0)

vorhanden=true;

i=0;

}

}

datei.close();

if(vorhanden==true)

cout<<endl<<suchname<<" ist in der Datei vorhanden"<<endl;

else

cout<<endl<<suchname<<" ist in der nicht Datei vorhanden"<<endl;

//getch();

}

















// ********** Methoden der abgeleiteten Klasse CPersonal **



// XXX Das ist der alte Konstruktor

CPersonal::CPersonal()

{

strcpy(Dateiname,"personal.txt");

}



// XXX Das ist der neue Konstruktor:

// XXX Es müssen die Argumente "vor", "nach" und "nummer" übergeben werden

CPersonal::CPersonal(char *vor, char *nach, int nummer)

{

strcpy(Dateiname,"personal.txt");

strcpy(Vorname, vor);

strcpy(Nachname, nach);

PersNr = nummer;

}





void CPersonal::eingeben()

{

cout<<"Personaldaten \n";

CPerson::eingeben();

cout<<"Personalnummer = ";

cin>>PersNr;

CPersonal::speichern();

}



void CPersonal::speichern()

{

ofstream datei;

datei.open(Dateiname,ios::app);

if(!datei)

cout<<"\nDatei kann nicht geoeffnet werden";

else

datei<< PersNr <<" "<<Vorname<<" "<<Nachname<<" # " << endl;

datei.close();

}



// XXX Siehe Kommentare im Post

void CPersonal::gibMichAus()

{

cout << PersNr <<" "<<Vorname<<" "<<Nachname<<" # " << endl;

}











// XXX Die liesPersonal-Funktion gehört zu keiner Klasse



void liesPersonal(vector<CPersonal*> &personal) {



char vorname[30],nachname[30],nummerString[30];

ifstream datei("personal.txt");

while(!datei.eof())

{

// eine Zeile lesen

datei >> nummerString;

datei >> vorname;

datei >> nachname;

datei.ignore(INT_MAX, '\n'); // Zeilenende-Zeichen ignorieren

if (datei.eof()) break;



int nummer = atoi(nummerString);



// Personal erstellen und in vector legen:

CPersonal *pers = new CPersonal(vorname, nachname, nummer);

personal.push_back(pers);

}

datei.close();

}





// XXX Eine neue Funktion, für die neuen Funktionen



void verwaltung()

{

// XXX Einen Vector erstellen

vector<CPersonal*> personal;



// XXX Personal lesen

liesPersonal(personal);



// XXX Personal ausgeben:

cout << "Personal: " << endl;

for (int i=0; i<personal.size(); i++) {

personal[i]->gibMichAus();

}



// XXX Zwei Personen vertauschen, und neu ausgeben

if (personal.size()>=2) {

CPersonal *tmp = personal[0];

personal[0] = personal[1];

personal[1] = tmp;



cout << "Personal, 0 und 1 vertauscht: " << endl;

for (int i=0; i<personal.size(); i++) {

personal[i]->gibMichAus();

}

}



}











// ********** Menue mit Hauptprogramm *********************







// XXX Ein paar kleine Hilfs-Funktionen - machen die

// XXX menue-Funktion übersichtlicher :-)

void personaldaten() {

char auswahl;

cout<<"\n\n*********Personaldaten********\n";

cout<<"Neueingabe von Daten ........n";

cout<<"\nAusgabe aller Daten .........a";

cout<<"\nSuchen einzelner Daten ......f";

cout<<"\nEnde ........................q";

cout<<"\nIhre Wahl = ";

cin>>auswahl;



CPersonal meinPersonal;

switch(auswahl)

{

case 'n':

case 'N': meinPersonal.eingeben(); break;

case 'a':

case 'A': meinPersonal.ausgeben(); break;

case 'f':

case 'F': meinPersonal.suchen(); break;

case 'q':

case 'Q': exit(-1); break;

}

}







void kundendaten()

{

char auswahl;

cout<<"\n\n*********Kundendaten**********\n";

cout<<"Neueingabe von Daten ........n";

cout<<"\nAusgabe aller Daten .........a";

cout<<"\nSuchen einzelner Daten ......f";

cout<<"\nEnde ........................q";

cout<<"\nIhre Wahl = ";

cin>>auswahl;

/*

CKunde meinKunde;

switch(auswahl)

{

case 'n':

case 'N': meinKunde.eingeben(); break;

case 'a':

case 'A': meinKunde.ausgeben(); break;

case 'f':

case 'F': meinKunde.suchen(); break;

case 'q':

case 'Q' :exit(-1); break;

}

*/

}







void menue()

{

char auswahl;



// XXX Eine Schleife um's menü...



do {

//system("clear");

cout<<"\n\n********Dateiverwaltung*******\n";

cout<<"Kundendaten .................k";

cout<<"\nPersonaldaten ...............p";

cout<<"\nVerwalung....................v";

cout<<"\nEnde ........................q";

cout<<"\nIhre Wahl = ";

cin>>auswahl;



if(auswahl=='p'||auswahl=='P') personaldaten();

if(auswahl=='k'||auswahl=='K') kundendaten();

if(auswahl=='v'||auswahl=='V') verwaltung();



}while(auswahl != 'q' && auswahl!='Q');



// XXX ... besser als hier nochmal "menue" aufzurufen!

//menue();

}







int main()

{

menue();

return 0;

}







bye





P.S: Die [Tags mit den eckigen Klammern] funktionieren hier nicht. Wenn man code postet, sollte man den in

<pre>

// Code

</pre>

Tags einschließen.





















geschrieben von

Login

E-Mail:
  

Passwort:
  

Beitrag anfügen

Symbol:
 
 
 
 
 
 
 
 
 
 
 
 
 

Überschrift: