fread problem mit struct und Binärdatei
Hi!!
So Der fehler ist im Code markiert. fwrite also in die Binärdatei schreiben funktioniert einwandfrei.
aber fread wieder auslesen aus der Binärdatei funktioniert rein gar nicht. Also wenn ich die Zeile
mit dem fread weglassen würde das Programm funktionieren...
Mfg
struct Datum
{
int tt;
int mm;
int jj;
};
struct Person
{
int pnr; //nr der Person
char name[30];
float gehalt;
Datum gebdat;
};struct Person pers;
void delpers();
void searchpers(int);
void getpers();
void updpers();
int main ()
{
/************Ausgabe Umlaute********/
char ue = "ü";
char oe = "ö";
char ae = "ä";
CharToOem(ue,ue);
CharToOem(oe,oe);
CharToOem(ae,ae);
/*************************************/
int aus,wid=1;
do
{
system("cls");
printf (" ------------- Bitte den Men%spunkt eingeben ! -----------------\n",ue);
printf ("| |\n");
printf ("| 1. Eingabe einer neuen Person |\n");
printf ("| 2. W%shlen (pnr) und Ausgeben einer Person |\n",ae);
printf ("| 3. W%shlen (pnr) und L%sschen einer Person |\n",ae,oe);
printf ("| 4. W%shlen (pnr) und Update einer Person |\n",ae);
printf ("| 5. Personen sortiert nach Namen ausgeben |\n");
printf ("| 6. Personen sortiert nach Geburtsdatum ausgeben |\n");
printf ("| 7. Personen sortiert nach Name und Geburtsdatum ausgeben |\n");
printf ("| 8. Reorganisation |\n");
printf ("| |\n");
printf (" --------------------------------------------------------------\n\n",ue);
printf (" >>> "); scanf("%i",&aus);
system ("cls"); //Clear Screen
switch(aus)
{
case 0:
wid==0;
break;
case 1:
getpers();
break;
case 2:
printf ("Gib Nummer der Person ein die du ausgeben willst : - ");
scanf ("%i",&pnr);
** searchpers(); **
break;
case 3:
printf ("Gib Nummer der Person ein die du l%sschen willst : - ",oe);
scanf ("%i",&pers.pnr);
delpers();
break;
case 4:
printf ("Gib Nummer der Person ein die du updaten willst : - ",oe);
scanf ("%i",&pers.pnr);
updpers();
break;
case 5:
break;
case 6:
break;
case 7:
break;
case 8:
break;
default:
printf (" // Falsche Eingabe //\n\n");
break;
}
}while(wid==1);
system("PAUSE");
return 0;
}
// Aufruf der Fuktion ....... Suchen einer Person, die in die Binärdatei gespeichert wurde
void getpers()
{
fp= fopen ("pers.txt","a+b");
printf ("-- Bitte Daten der Person Eingeben --\n\n");
printf ("1. Nr = "); scanf ("%i",&pers.pnr);
printf ("2. Name = "); scanf ("%s",&pers.name);
printf ("1. Gehalt = "); scanf ("%f",&pers.gehalt);
printf ("1. tt.mm.jj = "); scanf ("%i.%i.%i",&pers.gebdat.tt,&pers.gebdat.mm,&pers.gebdat.jj);
fwrite (&pers,sizeof(pers),1,fp); //Hier wird in die Binärdateigeschrieben also die geraden eingegebene Werte.
fclose (fp);
}
**void searchpers(int pnr)
{
fp= fopen ("pers.bin", "r+b"); //Die Datei Binär öffnen
fseek(fp, 0L, SEEK_SET); //Datei pointer zeigt danach auf den Anfang
if(fp==NULL)
printf ("\nDatei wurde nicht gefunden!\n\n");
do
{
fread (&pers, sizeof(pers),1,fp); //////////////////////////////////// Genau hier stürzt er immer ab aber warum?
}while(pnr!=pers.pnr); // Also er macht die Schleife so lange bis pnr (das gesuchte) gleich dem pnr im
//gerade eingelsen struct aus der Textdatei ist
//Wenn gefunden
printf ("\n\n -- Die gesuchte Person - Pnr: %s - ist: --\n\n",pers.pnr);
printf (" 1. Name = %s\n",pers.name);
printf (" 2. Gehalt = %f\n",pers.gehalt);
printf (" 3. tt.mm.jj = %i.%i.%i\n\n",pers.gebdat.tt,pers.gebdat.mm,pers.gebdat.jj);
fclose(fp); //Schließen der Datei
printf ("\n\n\n");
system ("PAUSE");
}**
So Der fehler ist im Code markiert. fwrite also in die Binärdatei schreiben funktioniert einwandfrei.
aber fread wieder auslesen aus der Binärdatei funktioniert rein gar nicht. Also wenn ich die Zeile
mit dem fread weglassen würde das Programm funktionieren...
Mfg
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 115167
Url: https://administrator.de/contentid/115167
Ausgedruckt am: 25.11.2024 um 22:11 Uhr
24 Kommentare
Neuester Kommentar
Augen auf, dann siehste das er unten ein Kommentar im Code zu stehen hat, wo steht:
" Genau hier stürzt er immer ab aber warum?"
Auch wenn das nicht so die feine Art ist tuen sich trotzdem fragen auf@Wuschel-Core. ^^
Wie lautet die Fehlermeldung?
Schon im Einzelschrittmodus durchs Programm gegangen?
KEINE Fehlerbehandlung vorhanden!!! (feof oder ferror)
Des Weiteren:
Wenn ich das richtig lese, willst du immer nur den ersten Datensatz aus fp auslesen und das solange deine Bedingung ungleich ist?
" Genau hier stürzt er immer ab aber warum?"
Auch wenn das nicht so die feine Art ist tuen sich trotzdem fragen auf@Wuschel-Core. ^^
Wie lautet die Fehlermeldung?
Schon im Einzelschrittmodus durchs Programm gegangen?
KEINE Fehlerbehandlung vorhanden!!! (feof oder ferror)
Des Weiteren:
do
{
fread (pers, sizeof(struct Person),1,fp);
}while(pnr!=pers.pnr);
Wenn ich das richtig lese, willst du immer nur den ersten Datensatz aus fp auslesen und das solange deine Bedingung ungleich ist?
Hallo wuschel-cOre,
also, erstmal bin ich ziemlich verwirrt,
Als ich mein letzten Borland 'C' Code vor ca 15 Jahren geschrieben habe, da gab's noch gewisse Syntaxregeln. So wurden z. B. Kommentare folgender Maßen gekennzeichnet, ansonsten wurde eine Syntax-Fehler ausgegeben.
Bei einer Zeile: // Kommentar für eine Zeile
Bei Blockzeilen: /* Am Anfang des Kommentarblocks und */ am Ende des Blocks
Dann schreibst Du noch Kommentare ohne irgendwas direkt hinter die Anweisungen
Zu meiner Zeit hätte das schon eine Menge an Compiler-Fehler verursacht.
Ausserdem solltest Du vielleicht mal die Funktion der Tab-Taste nutzen, um Deinen Code etwas übersichtlicher zu gestalten(Wartungsfreundlicher).
Gruß Dieter
PS. Nutze die Formatireungshilfe für Code. 1.Zeile = <$code> und letzte Zeile = <$/code> aber ohne das Dollarzeichen.
also, erstmal bin ich ziemlich verwirrt,
Als ich mein letzten Borland 'C' Code vor ca 15 Jahren geschrieben habe, da gab's noch gewisse Syntaxregeln. So wurden z. B. Kommentare folgender Maßen gekennzeichnet, ansonsten wurde eine Syntax-Fehler ausgegeben.
Bei einer Zeile: // Kommentar für eine Zeile
Bei Blockzeilen: /* Am Anfang des Kommentarblocks und */ am Ende des Blocks
Dann schreibst Du noch Kommentare ohne irgendwas direkt hinter die Anweisungen
Zu meiner Zeit hätte das schon eine Menge an Compiler-Fehler verursacht.
Ausserdem solltest Du vielleicht mal die Funktion der Tab-Taste nutzen, um Deinen Code etwas übersichtlicher zu gestalten(Wartungsfreundlicher).
Gruß Dieter
PS. Nutze die Formatireungshilfe für Code. 1.Zeile = <$code> und letzte Zeile = <$/code> aber ohne das Dollarzeichen.
Hallo wuschel-cOre,
großes Lob. Sieht doch gleich viel besser aus
Gruß Dieter
großes Lob. Sieht doch gleich viel besser aus
Gruß Dieter
Hallo wuschel-cOre,
Versuch mal das:
Normaler übergibst Du ja einen Buff-Pointer, aber hier musst Du, wenn ich nicht irre die Adresse (&pers) der Struct übergeben?
Probiers aus. Ist halt schon sehr lange her.
Gruß Dieter
Versuch mal das:
fread (&pers, sizeof(struct Person),1,fp);
Normaler übergibst Du ja einen Buff-Pointer, aber hier musst Du, wenn ich nicht irre die Adresse (&pers) der Struct übergeben?
Probiers aus. Ist halt schon sehr lange her.
Gruß Dieter
Hi !
Ja ja damals gab es auch noch keine automatische Code Komplettierung, wir mussten den Kopf noch selber anstrengen.
Die heutigen IDEs, lassen doch jeden Blödsinn durchgehen. Seit dem ganzen .net Krempel, gibt es Entwickler die zwar hervorragende Kenntnisse in C++, C# oder VB haben aber nicht mal die einfachsten Hintergrundkenntnisse über das Ziel-OS haben. Wie sonst kann ich mir solchen Schwachsinn erklären, dass es Applikationen gibt, in denen z. B, die Windows Systempfade oder die Netzwerkkonfiguration hardgecoded wurden.
Mei mei mei
mrtux
Zitat von @76109:
Als ich mein letzten Borland 'C' Code vor ca 15 Jahren
geschrieben habe, da gab's noch gewisse Syntaxregeln. So wurden
Als ich mein letzten Borland 'C' Code vor ca 15 Jahren
geschrieben habe, da gab's noch gewisse Syntaxregeln. So wurden
Ja ja damals gab es auch noch keine automatische Code Komplettierung, wir mussten den Kopf noch selber anstrengen.
Zu meiner Zeit hätte das schon eine Menge an Compiler-Fehler
verursacht.
verursacht.
Die heutigen IDEs, lassen doch jeden Blödsinn durchgehen. Seit dem ganzen .net Krempel, gibt es Entwickler die zwar hervorragende Kenntnisse in C++, C# oder VB haben aber nicht mal die einfachsten Hintergrundkenntnisse über das Ziel-OS haben. Wie sonst kann ich mir solchen Schwachsinn erklären, dass es Applikationen gibt, in denen z. B, die Windows Systempfade oder die Netzwerkkonfiguration hardgecoded wurden.
Mei mei mei
mrtux
Hallo mrtux,
das sind die Zeichen der Zeit. Programmieren per Drag&Drop
Für's Denken bleibt da nicht mehr soviel viel Zeit.
Gruß Dieter
das sind die Zeichen der Zeit. Programmieren per Drag&Drop
Für's Denken bleibt da nicht mehr soviel viel Zeit.
Gruß Dieter
Hi !
Dagegen habe ich eigentlich nix, wenn Man(n) oder Frau weiss, was er/sie tut. Oft liegt aber genau da das Problem und nicht an der verwendeten IDE
...und wir Admins müssen den Schrott dann immer ausbaden
mrtux
Zitat von @76109:
Hallo mrtux,
das sind die Zeichen der Zeit. Programmieren per Drag&Drop
Hallo mrtux,
das sind die Zeichen der Zeit. Programmieren per Drag&Drop
Dagegen habe ich eigentlich nix, wenn Man(n) oder Frau weiss, was er/sie tut. Oft liegt aber genau da das Problem und nicht an der verwendeten IDE
Für's Denken bleibt da nicht mehr soviel viel Zeit.
...und wir Admins müssen den Schrott dann immer ausbaden
mrtux
Zitat von @76109:
Hallo wuschel-cOre,
großes Lob. Sieht doch gleich viel besser aus
Gruß Dieter
<OT>Hallo wuschel-cOre,
großes Lob. Sieht doch gleich viel besser aus
Gruß Dieter
Moin wuschel-cOre,
moin maretz, H41mSh1COR, mrtux und didi1954,
@wuschel-cOre
Ich habe Deinen Code im -sagen wir mal großzügig- "Beitrag" in Code-Tags gesetzt.
Das war jetzt der zweite lieblos hingerotzte Beitrag innerhalb von 2 Tagen.
"Drei Mal ist Bremer Recht" heißt es bei mir zu Haus - Du solltest keine zu optimistischen Analogien für Deine Beiträge daraus ableiten.
Versprechen meinerseits:
Den nächsten Mir-doch-egal-Beitrag werde ich im Fluge löschen (ohne Umweg über Papierkorb).
Grüße
Biber
</OT>
Hallo H41mSh1C0R,
wie gesagt, es ist schon sehr lange her.
also, ich würde vorschlagen den Code mit dem Debugger zu testen. Das ist die einfachste Methode einen Fehler zu finden
Aber vermutlich muss der "pers" erst noch einen (sizeof) Heap-Speicherplatz anfordern. Oder den Pointer weglassen, dann belegt die Struct Person Speicherplatz im Datensegment und kann mit "&Person" übergeben werden. So oder so ähnlich.
Gruß Dieter
PS. Wenns hilft. Ich habe noch eine uralte CD gefunden:
oder
wie gesagt, es ist schon sehr lange her.
also, ich würde vorschlagen den Code mit dem Debugger zu testen. Das ist die einfachste Methode einen Fehler zu finden
Aber vermutlich muss der "pers" erst noch einen (sizeof) Heap-Speicherplatz anfordern. Oder den Pointer weglassen, dann belegt die Struct Person Speicherplatz im Datensegment und kann mit "&Person" übergeben werden. So oder so ähnlich.
Gruß Dieter
PS. Wenns hilft. Ich habe noch eine uralte CD gefunden:
struct DREC {
DB_ ATTR;
DW_ TIME;
DW_ DATE;
DD_ SIZE;
DB_ NAME [13];
DB_ RES0 [8];
VD_ *DPTR;
};
struct DREC *DINFO;
if ( heapinit (DINFO, sizeof (struct DREC) * 1536, 0) ) exit (1);
struct { DD_ SZ;
DB_ AR;
DB_ AH;
DB_ AS;
DB_ AD;
DB_ AA;
DW_ DT;
DW_ DM;
DW_ DJ;
DW_ TH;
DW_ TM;
DW_ TS;
} FINFO;
getftime ( hdl, &FINFO.TS );
Zitat von @Biber:
@wuschel-cOre
Ich habe Deinen Code im -sagen wir mal großzügig "Beitrag" in Code-Tags gesetzt.
@wuschel-cOre
Ich habe Deinen Code im -sagen wir mal großzügig "Beitrag" in Code-Tags gesetzt.
Hallo Biber,
OK, dann nehme ich mein großes Lob zurück und gebe es an Dich weiter Irgendwie hat mich das gleich daran errinnert, als DU meinen ersten Code so schön formatiert hattest. War doch verdächtig perfekt formatiert.
Hallo mrtux,
da bin ich aber froh, dass ich kein Admin bin und das ganze etwas lockerer sehen kann
Gruß Dieter
Zitat von @wuschel-cOre:
sorry wegen den formatierungen und der schlechten Beschreibung
wollte eig. darauf hinaus was beim fread der fehler war bzw. ist.
Habe noch einmal alles überarbeitet!.
Moin wuschel-cOre,sorry wegen den formatierungen und der schlechten Beschreibung
wollte eig. darauf hinaus was beim fread der fehler war bzw. ist.
Habe noch einmal alles überarbeitet!.
danke Dir für das Überarbeiten.
Ist Deine Frage damit beantwortet (gelöst) oder sind noch Fragen offen?
Grüße
Biber
Hallo wuschel-cOre,
Prima, Problem gelöst
Falls Deine Programme mit der Zeit komplexer werden, würde ich Dir dringend empfehlen, Dich mit den Debugger-Funktionen vertraut zu machen, da findest Du einen Fehler in der Regel viel schneller und man lernt einiges dazu. Ideal währe es natürlich, wenn Du Dir noch Assembler-Kenntnisse aneignen würdest, damit Du auch im Assembler-Modus debuggen kannst. Dann siehst Du auch den ganzen Ablauf und was im Hintergrund so vieles unnötige passiert. Das sind zum einen Bibliotheken-Schrott und zum anderen, die falsche Auswahl einer Funktion z.B. Printf, Prints oder Puts. Was ist der Unterschied und welcher Aufwand
wird letztendlich beim Einbinden von Bibliotheksmodulen betrieben. Das soll jetzt nur mal Aufzeigen, dass man wesentlich effektiver programmieren kann, wenn man den ganzen Ablauf nachvollziehen kann.
Gruß Dieter
Prima, Problem gelöst
Falls Deine Programme mit der Zeit komplexer werden, würde ich Dir dringend empfehlen, Dich mit den Debugger-Funktionen vertraut zu machen, da findest Du einen Fehler in der Regel viel schneller und man lernt einiges dazu. Ideal währe es natürlich, wenn Du Dir noch Assembler-Kenntnisse aneignen würdest, damit Du auch im Assembler-Modus debuggen kannst. Dann siehst Du auch den ganzen Ablauf und was im Hintergrund so vieles unnötige passiert. Das sind zum einen Bibliotheken-Schrott und zum anderen, die falsche Auswahl einer Funktion z.B. Printf, Prints oder Puts. Was ist der Unterschied und welcher Aufwand
wird letztendlich beim Einbinden von Bibliotheksmodulen betrieben. Das soll jetzt nur mal Aufzeigen, dass man wesentlich effektiver programmieren kann, wenn man den ganzen Ablauf nachvollziehen kann.
Gruß Dieter
Hallo H41mSh1C0R,
ich denke nicht, dass Deine Referenz fehlerhaft ist.
Der Unterschied liegt nur in der Definition einer Structur (siehe meine Beispiele). Vergleichbar mit char str[80] und char *str.
Im 1.Fall ist die Structur nur definiert und hat noch keinen Speicherplatz. Ihr wird ein *Null-Pointer zugewiesen, für den z.B. mit Malloc erst ein Speicherplatz auf dem Heap angefordert werden muss und der *Pointer dann die Adresse auf diesen Speicherplatz enthält.
Im 2.Fall ist der Structur bereits Speicherplatz im Globalen Datensegment zugewiesen. D.h. hier muss dann die Adresse mit dem Adress-Operator (&) übergeben werden.
Die Funktion Fread erwartet als Parameter einen Pointer (void *ptr) auf die Structur.
Gruß Dieter
ich denke nicht, dass Deine Referenz fehlerhaft ist.
Der Unterschied liegt nur in der Definition einer Structur (siehe meine Beispiele). Vergleichbar mit char str[80] und char *str.
Im 1.Fall ist die Structur nur definiert und hat noch keinen Speicherplatz. Ihr wird ein *Null-Pointer zugewiesen, für den z.B. mit Malloc erst ein Speicherplatz auf dem Heap angefordert werden muss und der *Pointer dann die Adresse auf diesen Speicherplatz enthält.
Im 2.Fall ist der Structur bereits Speicherplatz im Globalen Datensegment zugewiesen. D.h. hier muss dann die Adresse mit dem Adress-Operator (&) übergeben werden.
Die Funktion Fread erwartet als Parameter einen Pointer (void *ptr) auf die Structur.
Gruß Dieter
Hi Dieter,
Also angewendet auf das Problem vom TE, greift Fall 2, weil mit fseek der Dateipointer an den Anfang gestellt wurde und dann mit fread bei jedem Durchlauf beginnend vom Anfang, immer Portionsweise ein Datensatz abgeholt wird.
Der Pointer auf die Struktur ist also immer die Adresse vom Anfang einer jeden Portion?
Sehe ich das richtig?
Gruß
H41mSh1C0r
Also angewendet auf das Problem vom TE, greift Fall 2, weil mit fseek der Dateipointer an den Anfang gestellt wurde und dann mit fread bei jedem Durchlauf beginnend vom Anfang, immer Portionsweise ein Datensatz abgeholt wird.
Der Pointer auf die Struktur ist also immer die Adresse vom Anfang einer jeden Portion?
Sehe ich das richtig?
Gruß
H41mSh1C0r
Hallo H41mSh1C0R,
also, mit den Funktionen FSEEK und FREAD hat das jetzt im Grunde nichts zu Tun.
Bei TE wird mit FREAD nacheinander immer nur ein Datensatz eingelesen und FSEEK steht automatisch auf dem nächsten Datensatz.
Es geht aber generell darum, wie ein Pointer anhand der einer Definition übergeben werden muss. Adresse (&) oder Pointer (*).
Wenn eine Funktion als Parameter einen Pointer (void *ptr) verlangt, dann muss das übergeben werden, was auf die Daten zeigt.
Im 1. Fall ist *DINFO ein Pointer. Er enthält z.B. durch Malloc initialisiert, die Adresse auf die Structur DREC. DINFO = [Zeiger auf Struct-DREC]
Im 2. Fall ist FINFO die Adresse. Hier stehen die Structur-Daten schon. FINFO = Struct-Daten und &FINFO = [Zeiger auf Struct-FINFO]
Ich weiß nicht, wie ich es besser erklären kann.
Gruß Dieter
also, mit den Funktionen FSEEK und FREAD hat das jetzt im Grunde nichts zu Tun.
Bei TE wird mit FREAD nacheinander immer nur ein Datensatz eingelesen und FSEEK steht automatisch auf dem nächsten Datensatz.
Es geht aber generell darum, wie ein Pointer anhand der einer Definition übergeben werden muss. Adresse (&) oder Pointer (*).
Wenn eine Funktion als Parameter einen Pointer (void *ptr) verlangt, dann muss das übergeben werden, was auf die Daten zeigt.
Im 1. Fall ist *DINFO ein Pointer. Er enthält z.B. durch Malloc initialisiert, die Adresse auf die Structur DREC. DINFO = [Zeiger auf Struct-DREC]
Im 2. Fall ist FINFO die Adresse. Hier stehen die Structur-Daten schon. FINFO = Struct-Daten und &FINFO = [Zeiger auf Struct-FINFO]
Ich weiß nicht, wie ich es besser erklären kann.
Gruß Dieter
Hallo H41mSh1C0R,
Yep, das siehst Du richtig. Offensichtlich habe ich Deine Frage wohl vorher Missverstanden.
Hoffe, nun ist alles geklärt.
Gruß Dieter
Yep, das siehst Du richtig. Offensichtlich habe ich Deine Frage wohl vorher Missverstanden.
Hoffe, nun ist alles geklärt.
Gruß Dieter