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 VorausHier 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