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.


Anmelden zum Antworten