Array aus Strukturen-Pointern
-
In ein Feld aus Zeigern auf Strukturen werden Werte aus einer Text-Datei eingelesen.
Das Einlesen funktioniert zwar, allerdings erscheint mir das alles total kompliziert und das Sortieren funktioniert leider auch nicht.#include <stdio.h> #include <stdlib.h> #include <string.h> #define DATEINAME_TXT "schueler.txt" typedef struct { char vorname[20]; char nachname[16]; struct { int tag; int monat; int jahr; } gebdatum; char klasse[6]; float selbstbehalt; } schueler_t; FILE*AnzahlSchuelerBestimmen(int *SchuelerAnzahl); void TxtSchuelerEinlesen(schueler_t **schueler, int SchuelerAnzahl, FILE*fp); void SchuelerSortieren(schueler_t **pSchueler1, int SchuelerAnzahl); void SchuelerAusgeben(schueler_t **schueler, int SchuelerAnzahl); int main(void) { int SchuelerAnzahl, i; FILE*fp = AnzahlSchuelerBestimmen(&SchuelerAnzahl); schueler_t **schueler = (schueler_t**)malloc(sizeof(schueler_t*)*SchuelerAnzahl); for(i=0; i < SchuelerAnzahl; i++) *(schueler+i) = (schueler_t*)malloc(sizeof(schueler_t)); TxtSchuelerEinlesen(schueler, SchuelerAnzahl, fp); SchuelerSortieren(schueler, SchuelerAnzahl); SchuelerAusgeben(schueler, SchuelerAnzahl); for(i=0; i < SchuelerAnzahl; i++) free(*(schueler+i)); // Zuerst die Spalten freigeben free(schueler); // Dann die Zeilen return 0; } FILE*AnzahlSchuelerBestimmen(int *SchuelerAnzahl) { FILE*fp = NULL; // Datei öffnen if((fp = fopen(DATEINAME_TXT, "r")) == NULL) { fprintf(stderr, "Datei \"%s\" konnte nicht geoeffnet werden!\n\n", DATEINAME_TXT); exit(1); } fscanf(fp, "%d\n", SchuelerAnzahl); return fp; } void TxtSchuelerEinlesen(schueler_t **schueler, int SchuelerAnzahl, FILE*fp) { int i; /** * Die Schüler sind in der Text-Datei immer nach folgendem System angeordnet: * Nachname Vorname JJJJ.MM.TT Klasse Selbstbehalt * zwischen jedem Wert befindet sich ein Tabulator **/ for(i=0; i < SchuelerAnzahl && !feof(fp); i++) { fscanf(fp, "%[^\t]\t%[^\t]\t%d.%d.%d\t%[^\t]\t%f\n", (*(schueler+i))->nachname, (*(schueler+i))->vorname, &(*(schueler+i))->gebdatum.jahr, &(*(schueler+i))->gebdatum.monat, &(*(schueler+i))->gebdatum.tag, (*(schueler+i))->klasse, &(*(schueler+i))->selbstbehalt); } fclose(fp); } void SchuelerSortieren(schueler_t **pSchueler1, int SchuelerAnzahl) { schueler_t *TempSchueler; schueler_t *pSchueler2 = *pSchueler1; schueler_t *pSchuelerAnfang = *pSchueler1; for(int i=0; i < SchuelerAnzahl; i++, (*pSchueler1)++) { for(int j=i+1; j < SchuelerAnzahl; j++, pSchueler2++) { if(strcmp((*pSchueler1)->nachname, pSchueler2->nachname) > 0) { TempSchueler = *pSchueler1; *pSchueler1 = pSchueler2; pSchueler2 = TempSchueler; } } } *pSchueler1 = pSchuelerAnfang; } void SchuelerAusgeben(schueler_t **schueler, int SchuelerAnzahl) { int i; printf("\n Nr. Nachname\t\t Vorname\t Geburtsdatum\t Klasse\t Selbstbehalt\n"); for(i=0;i<80;i++) putchar(196); // Überschriften unterstreichen (80 = max. Standard-Breite der Konsole) for(i=0; i < SchuelerAnzahl; i++, schueler++) { printf(" %2d. ", i+1); // Katalognummer (rechtsbündig) printf("%-19s ", (*schueler)->nachname); // Nachname (max. 19 Zeichen, linksbündig) printf("%-15s ", (*schueler)->vorname); // Vorname (max. 15 Zeichen, linksbündig) printf("%02d.%02d.%02d\t ", (*schueler)->gebdatum.tag, (*schueler)->gebdatum.monat, (*schueler)->gebdatum.jahr); // TT.MM.JJJJ printf("%s\t ", (*schueler)->klasse); // Klasse printf("EUR %.2f\n", (*schueler)->selbstbehalt); // Selbstbehalt } }
Vielleicht kann mir ja jemand sagen, was ich beim Sortieren falsch mache und ob das Zeiger-Feld so passt, wie es ist....
-
viele deiner variablennamen sind zu lang.
guck dir sort() oder qsort() an. damit kannst du deine daten einfach und schnell sortieren.
viele deiner **pointer kannst du auf *pointer reduzieren, wenn du sie innerhalb der funktionen eh nur dereferenzierst.