title image


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





void CKunde::gibMichAus()

{

cout << KundenNr <<" "<
}



Diese Funktion gibt nur die Kundennummer, Vorname, Nachname aus den Variablen aus, immer nur ein Satz



Ja. Wenn man z.B. 100 Kunden anlegt, will man ja nicht immer die Daten von allen Kunden ausgeben, sondern auch mal die Daten von einem einzelnen Kunden. Deswegen Objektorientierung: Man überlegt sich (erstmal ohne Code, nur ganz allgemein) was man mit einem einzelnen(!) Kunden machen können soll. Wenn man alle Kunden ausgeben will, ist das nichts, was ein einzelner Kunde machen kann. (Wenn du Kunde bei e-Bay bist, kannst du auch nicht für alle anderen Kunden ein Gebot abgeben, sondern nur für dich).







void liesKunden(vector<CKunde*> &kunden) {



Funktion liesKunde in dem Vektor ist die Klasse CKunde angelegt und die Kunden werden da hinterlegt



Sie liest alle Kunden, die in der Datei stehen, und schreibt die Kunden in einen Vector. Dieser vector kann Objekte vom Typ CKunde* aufnehmen. (Genaugenommen enthält er also Zeiger auf Kunden)









int nummer = atoi(nummerString);



nummer wird mit nummerString belegt(erster Wert aus der Datei)

WAS IST atoi????



atoi ist (wie man auch erfährt, wenn man danach googlet ;-)) eine Funktion, die einen char-Array liest, und daras einen int-Wert macht:

int zahl = atoi("123"); // 'zahl' hat jetzt den Wert 123









// Personal erstellen und in vector legen:

CKunde *kund = new CKunde(vorname, nachname, nummer);

kunde.push_back(kund);

}



??? Neue Klasse CKunde hat die Variablen Name, Vorname und Nummer; wird zurückgepusht ??? wohin???



Das 'push_back' bedeutet nur, daß der neue Kunde am Ende des vectors eingefügt wird. (mit 'push_front' würde er am Anfang des Vectors eingefügt werden). Als Beispiel:



vector<CKunde> kunden; // Vecotorinhalt: []

kunden.push_back(new Kunde("Kunde1")); // Vecotorinhalt: [Kunde1]

kunden.push_back(new Kunde("Kunde2")); // Vecotorinhalt: [Kunde1 | Kunde2]

kunden.push_back(new Kunde("Kunde3")); // Vecotorinhalt: [Kunde1 | Kunde2 | Kunde3]

kunden.push_front(new Kunde("Kunde0")); // Vecotorinhalt: [Kunde0 | Kunde1 | Kunde2 | Kunde3]











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



void CKunde::kundenVerwaltung()

{

vector kunde; //einen Vektor erstellen

liesKunde(kunde);





Die neuen Funktionen (sortieren, bearbeiten usw.) Stehen im Moment ja noch "einfach so" im Code. Wenn es "gut" und leicht erweiterbar sein sollte, würde man sich dafür eine eigen Klasse machen. Z.B. "PersonenVerwaltung".



Wie so eine Klasse aussehen könnte, ist ganz unten beschrieben. Aber wenn das zu kompliziert ist, kannst auch einfach zwei getrennte Funktionen schreiben:

kundendatenVerwaltung();

und

personaledatenVerwaltung();

Das wäre vermutlich die einfachere Lösung, allerdings von der Struktur her halt nicht so schön.









// Personal ausgeben:

cout << "Kunde: " << endl;

for (int i=0; i
kunde[i]->gibMichAus();

}

kunde.size=Anzahl der Einträge in der Datei, entsprechend dem Vektor(???)



Genau: Man liest beliebig viele Kunden aus der Datei und schreibt die in den vector. Mit vector.size() erfährt man dann, wieviele Kunden in dem vector stehen.





warum ein ->??? Kunde wird ausgegeben



Der -> steht dort, weil in dem vector ja genaugenommen nicht "CKunde"-Objekte stehen, sondern nur Zeiger auf CKunde-Objekte. Das macht z.B. das Vertauschen und Bearbeiten etwas einfacher. (Abgesehen davon: Auch die Programmierung an sich, weil man z.B. keinen Zuweisungsoperator überladen muß etc....)









// Zwei Personen vertauschen, und neu ausgeben

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

CKunde *tmp = kunde[0];

kunde[0] = kunde[1];

kunde[1] = tmp;



kunden werden vertauscht, kann man ausbauen, mit Bubblesort oder ähnlichem



Genau deswegen habe ich dieses Beispiel angegeben ;-)







-------------------------------------------------------------------------------



So, nun kommen weitere Fragen :-)

Weiß ich stelle mich dabei an, aber bringt mir nix, enn ich das nicht versteheh und davon überzeugt bin was da steht.



Kann man das ausgeben des Vektor und das Sortieren auch irgenwie trennen? Fur das ausgeben brauche ich meines erachtens ja nur den ersten Teil aber der sortieren Teil baut darauf doch auf oder nicht?



Man kann (und sollte) es trennen. Die 'verwaltung'-Funktion sollte nur die wichtigsten Funktionen verdeutlichen, die du vmtl. für die Verwaltung brauchen wirst. Das dann geeignet zusammenzubauen, zu Funtkionen, die das gewünschte erledigen, wollte ich dir überlassen ;-)





Also das auch einmal habe: gibmirallesaus() und sortiermirdenkrams()

Dadurch würde sich meine Funktion ausgeben() ja erübrigen.



Genau. Wobei da schon ein Unterschied ist: 'ausgeben' hat bisher direkt aus der Datei gelesen. Die Neue Funktion würde den Inhalt des Vectors ausgeben. Was aber imho "besser" wäre, weil die Funktion, alle Kunden auszugeben, eigentlich nichts in der "CKunde"-Klasse verloren hat...







Also ich weiß nicht genau aber ich habe es so nicht erkannt. Aber die Einträge verändern oder löschen kann ich nicht bzw wird in dem Programm nicht gemacht oder?



wobei wird das damit nicht zurückgeschrieben in die datei?



kunde.push_back(kund);



Nein (siehe oben). Damit wird der Kunde in den Vector geschrieben. Um die veränderten Daten wieder in die Datei zu schreiben, würde man sich eine eigene Funktion machen. Dafür könntest du die (im vorigen Post beschriebene) Funktion verwenden:



// Ausgeben einer Person

void CPerson::ausgeben(ostream &output) { /* macht nichts */ }



// Ausgeben eines Kunden

void CKunde::ausgeben(ostream &output) {

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

}



// Ausgeben eines Personals

void CPersonal::ausgeben(ostream &output) {

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

}



...



// Gehrört zu keiner Klasse (bzw. zu einer Klasse "Personenverwaltung")

void alleAusgeben(vector personen, ostream &output) {

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

}

}



Damit könnte man dann sowohl einen vector mit Personal als auch einen Vector mit Kunden ausgeben:



// Personal lesen

vector<CPersonal*> personal;

liesPersonal(personal);



//... (hier jetzt verändern usw.)



// Personal schreiben:

ofstream datei("personal.txt");

alleAusgeben(personal, datei);



// ----- oder für Kunden:



// Kunden lesen

vector<CKunde*> kunden;

liesKunden(kunden);



//... (hier jetzt verändern usw.)



// Kunden schreiben:

ofstream datei("kunden.txt");

alleAusgeben(kunden, datei);











Dann könnte man ja zum Beispiel, eine Personal- bzw. Kundennummer eingeben, es wird überprüft ob die enthalten ist, ist sie enthalten wird der gesamte Eintrag angezeigt, was zu der nummer gehört. dann könnte man ja auswählen ob der eintrag gelöscht werden soll oder nicht. bei eingabe ja wird gelöscht bei nein programm beendet.



Naja - ob das Programm gleich beendet werden muß....? Man könnte auch einfach "nichts" machen (und zurück ins menue kommen...). Die Funktion zum Löschen könnte einen vector übergeben bekommen, und die Position des Eintrags, der gelöscht werden soll:



void löschen(vector<CPerson*> personen, int position)

{

// Lösche die Person an der angegebenen 'position' im Vector:



delete personen[position]; // Speicher freigeben

personen.erase(personen.begin()+position); // Zeiger aus vector entfernen

}





void CKunde::löschenundsuchen()

{

char kundennummer;

char antwort;

cin>>kundennummer

if (kundennummer==einem Eintrag aus der datei) {

cout<
cout<<"Soll dieser Eintrag gelöscht werden? Y/N ";

cin>>antwort;

if(antwort=='Y'||auswahl=='y') löschen(kunden, zeilenNummer);

if(antwort=='N'||auswahl=='n') cout << "Nicht löschen...." << endl;

}

else cout << "Diese Nummer wurde bisher nicht vergeben";

}













Nochmal: Es wäre am geschicktesten, die Personenverwaltung in eine eigene Klasse zu legen. (D.h. alle Funktionen, bei denen ich irgendwas CKunde:: durchgestrichen habe). Das Programm soll wohl diese Woche fertig werden, darum weiß ich nicht, ob du die Zeit dafür aufbringen kannst und willst, aber grundsätzlich könnte man das ganz allgemein schreiben:



class PersonenVeraltung {

private:



// Nimmt Zeiger auf Personen (Kunden oder Personal) auf

vector<CPerson*> personen;





public:



// Konstruktor: Liest Personen aus Datei, schreibt sie in den vector

PersonenVerwaltung(char *dateiname);



// Gibt den inhalt des vectors aus - entweder nach cout, oder in eine Datei

void schreibePersonen(ostream &output);



void sortierePersonen();



// Löscht den angegebenen Eintrag des vectors

lösche(int position);



...

};





Der Vorteil ist offensichtlich: Man hat alle Funktionen, die mit der Verwaltung von Personen zu tun haben, in EINER Klasse gekapselt. Wenn man sich bemüht, die Funktionen so allgemeingültig zu schreiben, kann man sowohl Personal als auch Kunden mit EINER Klasse (eben PersonenVerwaltung) verwalten.



Wenn du es nicht Umsetzen willst, könntest du aber zumindest irgendwo im Quellcode (wo der Lehrer es liest! ;-)) eine Bemerktung schreiben, daß man das (wenn man mehr Zeit hätte) alles etwas schöner und allgemeingültiger schreiben könnte ;-)



bye







geschrieben von

Login

E-Mail:
  

Passwort:
  

Beitrag anfügen

Symbol:
 
 
 
 
 
 
 
 
 
 
 
 
 

Überschrift: