Auslesen einer Datei mit fread



  • Hey Liebe Forum-User ich soll für die Schule aus der Datei
    "Station10.dat"mit fread den Inhalt auslesen und auf Konsole
    wiedergeben. Aus Irgendwelchen Gründen bin ich an der Ausgabe
    gescheitert. Ich wäre über nen kleinen Tipp sehr dankbar.
    Die Suchfunktion war leider ohne Erfolg. Bedanke mich im Voraus

    Hier der Code:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #pragma warning (disable:4996)
    
    struct wetterstation
    {
    	float		gl;
    	float		gb;
    	float		temperatur;
    	float		windgeschwindigkeit;
    	short int	niederschlag;
    	short int	rel_luftfeuchte;
    } ;
    
    void main(void)
    
    {
    
    	int laenge;	
    	FILE *f;
    
    	struct wetterstation *p=NULL;
    
    	//p = (struct wetterstation*)malloc (sizeof(struct wetterstation));
    
    	f=fopen("Station10.dat","rb");
    	if(f!=NULL)
    	{
    		printf("Zugriff auf Dateti erfolgt\n\n");
    		//Ans Ende der Datei
    		fseek(f,0,SEEK_END);
    		//Groesse Ermitteln
    		laenge=ftell(f) / sizeof(struct wetterstation);
    		//Zurück an den Anfang der Datei
    		rewind(f);
    		printf("In der Datei sind %i Bloecke\n", laenge);
    		//Datei Schließen
    		fclose(f);
    	}
    	else if(f==NULL)
    	{
    		printf("Fehler");
    	}
    
    	/*fread(&p,sizeof(struct wetterstation),5,f); 
              Hier bin dann gescheitert ((*/
    
    }
    

    Mit freundlichen Grüßen

    rse7en



  • das Thema hat sich erledigt hatte

    fread(&p,sizeof(struct wetterstation),1,f); // Der Fehler war &p
    

    //korrektur

    fread(p,sizeof(struct wetterstation),1,f);
    

    best greetz



  • In Z 41 hast du die Datei schon wieder geschlossen, dann kannst du in Z 48 nicht mehr von dort lesen.
    Zu dem malloc() aus Z 27 fehlt ein free() am Ende (und casten muß man es auch nicht).
    Du forderst in Z 27 nur Speicher für eine Struktur-Instanz an, willst aber in Z 48 5 Instanzen einlesen. Das ist keine gute Idee.
    p ist schon ein Zeiger auf einen Speicherbereich, das & in Z 48 ist schlecht, weil du die Adresse des Zeigers erhälst, aber den Zeiger willst. Lass es weg.



  • jo genau danke für die tipps .. hier nochmal der komplette code

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #pragma warning (disable:4996)
    
    struct wetterstation
    {
    	float		gl;						//geograph. Laenge
    	float		gb;						//geograph. Breite	
    	float		temperatur;	
    	float		windgeschwindigkeit;
    	short int	niederschlag;
    	short int	rel_luftfeuchte;
    } ;
    
    void main(void)
    
    {
    
    	int laenge;	
    	FILE *f;
    
    	struct wetterstation *p = (struct wetterstation*) malloc (sizeof(struct wetterstation));
    
    	//p = (struct wetterstation*)malloc (sizeof(struct wetterstation));
    
    	f=fopen("Station10.dat","rb");
    	if(f!=NULL)
    	{
    		printf("Zugriff auf Dateti erfolgt\n\n");
    		fseek(f,0,SEEK_END);
    		laenge=ftell(f) / sizeof(struct wetterstation);
    		rewind(f);
    		printf("In der Datei sind %i Bloecke\n", laenge);
    
    		fread(p,sizeof(struct wetterstation),1,f);
    		printf("%f\n",p->gl);
    		printf("%f\n",p->gb);
    		printf("%f\n",p->temperatur);
    		printf("%f\n",p->windgeschwindigkeit);
    		printf("%h\n",p->niederschlag);
    		printf("%h\n",p->rel_luftfeuchte);
    
    		fread(p,sizeof(struct wetterstation),2,f);
    		printf("%f\n",p->gl);
    		printf("%f\n",p->gb);
    		printf("%f\n",p->temperatur);
    		printf("%f\n",p->windgeschwindigkeit);
    		printf("%h\n",p->niederschlag);
    		printf("%h\n",p->rel_luftfeuchte);
    
    		fread(p,sizeof(struct wetterstation),3,f);
    		printf("%f\n",p->gl);
    		printf("%f\n",p->gb);
    		printf("%f\n",p->temperatur);
    		printf("%f\n",p->windgeschwindigkeit);
    		printf("%h\n",p->niederschlag);
    		printf("%h\n",p->rel_luftfeuchte);
    
    		fread(p,sizeof(struct wetterstation),4,f);
    		printf("%f\n",p->gl);
    		printf("%f\n",p->gb);
    		printf("%f\n",p->temperatur);
    		printf("%f\n",p->windgeschwindigkeit);
    		printf("%h\n",p->niederschlag);
    		printf("%h\n",p->rel_luftfeuchte);
    
    		fread(p,sizeof(struct wetterstation),5,f);
    		printf("%f\n",p->gl);
    		printf("%f\n",p->gb);
    		printf("%f\n",p->temperatur);
    		printf("%f\n",p->windgeschwindigkeit);
    		printf("%h\n",p->niederschlag);
    		printf("%h\n",p->rel_luftfeuchte);
    
    	}
    	else if(f==NULL)
    	{
    		printf("Fehler");
    	}
    }
    


  • jo genau danke für die tipps

    Warum hast du sie dann nicht beherzigt?

    Du solltest vielleicht auch den dritten Parameter von man: fread nachschlagen. Ich denke mal, daß dort immer 1 stehen sollte. fread liest (wenn noch was da ist) immer size*nmemb Bytes, und setzt das aktuelle Byte auf das nächste (wie üblich bei Eingabefunktionen).



  • Außerdem sollte das Auslesen der Wetterdaten wohl am besten mittels einer Schleife geschehen (wenn schon die Anzahl in 'laenge' gespeichert wird)...



  • jo jo werde dafür ne schleife heute programmieren .. 😃 wenn ich es feddich hab poste ich es dann nochmal rein 🤡



  • rse7en schrieb:

    jo jo werde dafür ne schleife heute programmieren .. 😃 wenn ich es feddich hab poste ich es dann nochmal rein 🤡

    Brauchst du nicht, das mach ich für dich. 😉

    while (laenge--) {
        fread(p,sizeof(struct wetterstation),1,f);    // nmemb immer eins
        printf("%f\n",p->gl);
        printf("%f\n",p->gb);
        printf("%f\n",p->temperatur);
        printf("%f\n",p->windgeschwindigkeit);
        printf("%h\n",p->niederschlag);
        printf("%h\n",p->rel_luftfeuchte);
    }
    


  • hab dein post zuspät gelesen 🙂 aber trotzdem danke so nun meine Fassung 🙂

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #pragma warning (disable:4996)
    
    struct wetterstation
    {
    	float			gl;						//geograph. Laenge
    	float			gb;						//geograph. Breite	
    	float			temperatur;	
    	float			windgeschwindigkeit;
    	unsigned short	niederschlag;
    	unsigned short 	rel_luftfeuchte;
    } ;
    
    void main(void)
    
    {
    	FILE *f;
    
    	struct wetterstation *p = (struct wetterstation*) malloc  ( sizeof(struct wetterstation*));
    
    	f=fopen("Station10.dat","rb");
    	if(f!=NULL)
    	{
    		int laenge;	
    
    		struct wetterstation *p = (struct wetterstation*) malloc  (5* sizeof(struct wetterstation*));
    
    		printf("Zugriff auf Dateti erfolgt\n\n");
    		fseek(f,0,SEEK_END);
    		laenge = ftell(f) / sizeof(struct wetterstation);
    		rewind(f);
    		printf("In der Datei sind %i Bloecke\n", laenge);
    
    		if(p!=NULL)
    		{
    			int i=0;
    			while(i<laenge)
    			{
    				fread(p,sizeof(struct wetterstation),laenge,f);
    				printf("Geographische Breite....:%f\n",p->gl);
    				printf("Geographische Laenge....:%f\n",p->gb);
    				printf("Temperatur in Celsius...:%f\n",p->temperatur);
    				printf("Windgeschwindigkeit.....:%f\n",p->windgeschwindigkeit);
    				printf("Niederschlag............:%hu\n",p->niederschlag);
    				printf("Luftfeuchte.............:%hu\n",p->rel_luftfeuchte);
    				++i;
    				++p;
    				printf("\n");
    			}
    		}
    		else if (p==NULL)
    		{
    			printf("Speicher konnte nicht reserviert werden");
    		}
    	}
    	else if(f==NULL)
    	{
    		printf("Fehler die Datei Station10.dat konnte nicht geöffnet werden");
    	}
    	free(p);
    	fclose(f);
    }
    


  • Sieht ordentlich aus. Ergibt bei mir aber noch einen Segmentation Fault, ich hab's behoben. Der Einfachheit halber poste ich die korrigierte Variante (inkl. einiger Verkürzungen):

    FILE *f;
    
        struct wetterstation *p;
    
        f=fopen("Station10.dat","rb");
        if(f!=NULL)
        {
            int laenge;
    
            // wenn man es so macht, reicht Speicher für *einen* Block,
            // also die 5 entfernt
            p = malloc (sizeof(struct wetterstation));
    
            printf("Zugriff auf Dateti erfolgt\n\n");
            fseek(f,0,SEEK_END);
            laenge = ftell(f) / sizeof(struct wetterstation);
            rewind(f);
            printf("In der Datei sind %i Bloecke\n", laenge);
    
            if(p!=NULL)
            {
                int i=0;
                while(i<laenge)
                {
                    // bitte beachten: dritter Parameter ist eins!
                    fread(p,sizeof(struct wetterstation),1,f);   
                    printf("Geographische Breite....:%f\n",p->gl);
                    printf("Geographische Laenge....:%f\n",p->gb);
                    printf("Temperatur in Celsius...:%f\n",p->temperatur);
                    printf("Windgeschwindigkeit.....:%f\n",p->windgeschwindigkeit);
                    printf("Niederschlag............:%hu\n",p->niederschlag);
                    printf("Luftfeuchte.............:%hu\n",p->rel_luftfeuchte);
                    ++i;
                    printf("\n");
                }
            }
            else
            {
                printf("Speicher konnte nicht reserviert werden");
            }
        }
        else
        {
            printf("Fehler die Datei Station10.dat konnte nicht geöffnet werden");
        }
    
        free(p);
        fclose(f);
    

    Die Variable i ist unnötig, weil man auch gleich die Variable laenge abwärts zählen könnte.
    Sehr wichtig: nachdem du pro Schleifendurchlauf genau einen Block einlesen willst, muß der dritte Parameter auch eins sein, wie oben angemerkt. Alternativ könntest du auch genug Speicher für fünf (laenge) Blöcke anfordern, und alle auf einmal einlesen.



  • Eine Sache hatte ich noch übersehen:
    Am Ende in Z 47 und Z 48 (meiner Variante) gibst du den Speicher und die Datei wieder zurück. Beides soll man aber nur machen, wenn man es vorher auch bekommen hat. So wie das jetzt ist, wird es aber auch gemacht, wenn man es nicht bekommen hat (also p oder f NULL waren). Da könnten dir Dämonen aus der Nase fliegen.



  • erstmal vielen dank für deine Hilfe und deine Bemühungen. Werde wenn ich es schaffen sollte heute abend nochma drüber schauen und versuchen die einigen kleinigkeiten noch zu beheben. Vielen Vielen Dank.

    best greetz

    rse7en


Log in to reply