Datensätze aus Datei auslesen und sortieren - Wer kann helfen?
-
Hallo,
habe ein kleines Programm für meinen Unterricht geschrieben. Das Programm soll eine Art Telefonbuch sein, um Namen und Vornamen und Telefonnummern anzusehen oder gezielt zu suchen.Wenn ich einen neuen Datensatz hinzufüge, müssten die Datensätze ja alphabetisch neu sortiert werden, also ausgelesen aus der Datei und dann neu nach Name oder anderen Kriterien sortiert werden. Wie kann ich das Sortieren der in der Datei abgelegten Datensätze organisieren.
Bisher habe ich mit fopen die Datei geöffnet und mit fwrite den Datensatz zurückgeschrieben. Die Suche erfolgte über fread. Sortiert habe ich bisher stets umständlich mit dem Bubblesort, also dem Dreieckstausch. Das darf alles nicht zu kompliziert sein.
Mein Problem ist nun, dass ich den Strukturarray nicht mehr als Array habe, wenn er aus der Datei ausgelesen worden ist. Der Datensatz wird ja Satzweise ausgelesen, nicht in Form eines Arrays.
Hier ein Auszug des Programms - das Auslesen der gespeicherten Datensätze:dat=fopen("Telefonbuch.dat","r");
cout << "Ausgabe der gespeicherten Daten " << endl<<endl;
cout << " Name Vorname Telefonnummer" << endl;
cout << "===================================================" << endl;
while(fread(&P,sizeof(P),1,dat)!=0)
{
cout << setw(15) << P.Name
<< setw(15) << P.Vorname
<< right<< setw(20)<< P.Telnummer << endl;
}
getch();
fclose(dat);Wie kann ich die Datensätze nun alphabetisch sortieren?
Kann jemand helfen?? DANKE!!!http://www.c-plusplus.net/forum/images/smiles/smile.gif

-
Hallo,
Erzeuge dir einen vector auf dem Typ deiner Telefonbucheinträge und füge in den deine eingelesenen Daten ein (mit push_back). Dann kannst du diesen vector sortieren z.Bsp. mit std::sort aus algorithm.
Wie hast du denn deine Telefonbuchdaten jetzt gespeichert?
-
Braunstein schrieb:
Hallo,
Erzeuge dir einen vector auf dem Typ deiner Telefonbucheinträge und füge in den deine eingelesenen Daten ein (mit push_back). Dann kannst du diesen vector sortieren z.Bsp. mit std::sort aus algorithm.
Wie hast du denn deine Telefonbuchdaten jetzt gespeichert?Hallo und DANKE!! für die Antwort, allerdings ist deine Lösung wohl eine Nummer zu kompliziert für mich. Am besten ich zeige mein Programm. Ich habe es lediglich sequentiell gespeichert. Es ist ein Konsolenprogramm für Anfänger von einem Anfänger.
#include <iostream.h>
#include <iomanip.h>
#include <conio.h>
//---------------------------------------------------------------------struct Person
{
char Name[21];
char Vorname[21];
char Telnummer[15];
};int main()
{int i = 0;
FILE *dat;
char was, noch_ein;
struct Person P;
char Suchname[20];
do
{
clrscr();
cout << "Programm: Erfassung von Telefonnummern " << endl;
cout << "========================================" << endl << endl;
cout << "Eingabe beenden mit ESC " << endl;
cout << "--------------------------------------" << endl;
/* Menü, mit ESC beenden /
cout<<"\n\n\nDateiverwaltung Telefonbuch ";
cout<<"\n\nWas moechten Sie tun ";
cout <<"\nNeue Namen zufuegen ==> 1";
cout <<"\nNamen ansehen ==> 2";
cout <<"\nNamen suchen ==> 3";
cout <<"\nDialog beenden ==> Y ";
cin >>was;
noch_ein='j'; / für Schleifen - Laufbedingung */
while (noch_ein=='j' && was=='1')
{
dat=fopen("Telefonbuch.dat","a+");
cout << "Eingabe neuer Stammdaten " <<endl;
cout << "Name : ";
cin >> P.Name;
cout << "Vorname : ";
cin >> P.Vorname;
cout << "Telefonnummer : ";
cin >> P.Telnummer;
fwrite(&P,sizeof(P),1,dat);
cout << "Noch einen? (j/n) ";
cin >> noch_ein;
fclose(dat);
clrscr();
i++;
}
if(was=='2')
{
dat=fopen("Telefonbuch.dat","r");
cout << "Ausgabe der gespeicherten Daten " << endl<<endl;
cout << " Name Vorname Telefonnummer" << endl;
cout << "===============================================" << endl;
while(fread(&P,sizeof(P),1,dat)!=0)
{
cout << setw(15) << P.Name
<< setw(15) << P.Vorname
<< right<< setw(20)<< P.Telnummer << endl;
}
getch();
fclose(dat);
}
if(was=='3')
{
dat=fopen("Telefonbuch.dat","r");
cout << "Welchen Namen suchen Sie? ";
cin >> Suchname;cout << " Name Vorname Telefonnummer" << endl;
cout << "===============================================" << endl;
while(fread(&P,sizeof(P),1,dat)!=0)
{
if(strcmp(Suchname,P.Name)==0)
{
cout << left << setw(15) << P.Name << left
<< setw(15) << P.Vorname
<< right<< setw(20)<< P.Telnummer << endl;
}
}
getch();
fclose(dat);
}}while(was!=89);
return 0;
-
dein freund heiss qsort
-
au haua aua schrieb:
dein freund heiss qsort
Cooler wäre sortiertes Einfügen in eine verkettete Liste, dann kann man auf Sortierfunktionen wie qsort und co. verzichten.
Es schadet aber nicht, qsort mal kennen zu lernen:
#include <stdlib.h> #define NAMELEN 64 #define TEL 32 struct Person { char Name[NAMELEN+1]; char Vorname[NAMELEN+1]; char Tel[TEL+1]; }; void Show( struct Person* P, unsigned N ) { int i; for ( i=0; i<N; i++ ) printf( "Name: %s\n", P[i].Name ); } int compare( const void *a, const void *b ) { return strcmp( ((struct Person*)a)->Name, ((struct Person*)b)->Name ); } void Sort( struct Person* P, unsigned N ) { qsort( (void *)P, N, sizeof( struct Person ), compare ); } #define N sizeof(P)/sizeof(*P) int main(int argc, char* argv[]) { struct Person P[3] = {0}; strcpy( P[0].Name, "zzzz" ); strcpy( P[1].Name, "kkk" ); strcpy( P[2].Name, "aaa" ); Show( P, N ); Sort( P, N ); puts("*******************************"); Show( P, N ); return 0; }
-
Leute, ihr seid im falschen Forum … hier ist C++.
-
Hallo Big Brother,
vielen Dank für deinen konkreten Vorschlag - werde ich mal ausprobieren.
Schön, dass bei deiner Antwort keine Arroganz zu lesen war.
Danke nochmal.
-
Wenn ich es unter C++ machen sollte, würde ich das irgendwie so versuchen:
(Bin selbst noch am lernen, daher habe ich mich mal direkt an dem Problem versucht).#include <iostream> #include <list> #include <fstream> #include <string> #include <iomanip> struct CPerson { std::string Name; std::string Vorname; std::string Telefonnummer; }; //Listentemplate fuer Personen auspraegen typedef std::list<CPerson> CPersonenListe; //Sortierkriterium festlegen (hier koennte mal auch weitere zum Sortieren z.B. nach Vorname anlegen) bool SortiereNachName_Praedikat(const CPerson& Datensatz1, const CPerson& Datensatz2) { return (Datensatz1.Name < Datensatz2.Name); } int main() { //Listenobjekt fuer Personendatensaetze anlegen CPersonenListe personenListe; //Stream zum Lesen aus Datei oeffnen std::ifstream DatenLeser("Telefonbuch.dat", std::ios_base::in); if(DatenLeser) { //aktuell gelesene Person CPerson aktuellerDatensatz; //Lese bis zum Ende der Datei while(!DatenLeser.eof()) { //Name lesen DatenLeser >> aktuellerDatensatz.Name; //Vorname lesen DatenLeser >> aktuellerDatensatz.Vorname; //Tel.-Nr. lesen DatenLeser >> aktuellerDatensatz.Telefonnummer; //in Liste ablegen personenListe.push_back(aktuellerDatensatz); } //nach Name sortieren personenListe.sort(SortiereNachName_Praedikat); //ausgeben for(CPersonenListe::iterator iIter = personenListe.begin(); iIter != personenListe.end(); ++iIter) { std::cout << std::setw(16) << std::left << "Name:" << iIter->Name << '\n' << std::setw(16) << std::left << "Vorname:" << iIter->Vorname << '\n' << std::setw(16) << std::left << "Telefonnummer:" << iIter->Telefonnummer << "\n\n"; } } else { //Ausgabe, falls Datenbank (Stream) nicht geoeffnet werden konnte std::cout << "Konnte Datei \"Telefonbuch.dat\" nicht oeffnen!\n"; } //Lesestream schliessen DatenLeser.close(); return 0; }
-
Hallo Tachyon
Soweit reichen meine Kenntnisse noch nicht.
Das ist denke ich der Weg, den Baunstein vorgeschlagen hat. Ich werde demnächst versuchen, dein Programm nachvollziehen zu können. Dazu muss ich aber noch ein wenig mehr studieren (Das Buch ist schon bestellt)
Habe vielen Dank!!!