Stupider Fseek-Fehler oder rekursiver Algo?
-
Hallo meine Lieben,
ich hoffe mir kann eventuell einer weiter helfen beim Debuggen des folgenden Codes...
Folgende Problemdarstellung:
- Die Eingaben werden in den Arbeitsspeicher übernommen und (teilweise) auch in die Datei gespeichert "musik_db.txt",
nur leider unregelmäßig und nicht wirklich strukturiert.- Zudem liest er mit bei der Auswahl "Ausgabe" nur eine einzige Zeile der Datei aus,
aber auch nur, wenn ich das Programm neu öffne und eine Eingabe erneut eingebe.
Nie gibt er mir (wie bei der Parallelen Speicherung in den Arbeitsspeicher) auch nur ansatzweise die 2. Zeile aus... Die erste sowieso nicht, wenn ich das Programm neu aufrufe,
als ob er nicht lesen kann, was in der ersten Zeile steht ...Die Datei "musik_db.txt" wird allerdings erstellt und zumindestens in der ersten Zeile werden die Werte meiner eingegebenen Variablen gespeichert.
Hab ich einen Denkfehler bei der fseek-Angabe
oder hab ich mir aus Versehen einen rek-Algo gebaut?Hmpf... Danke für die Mithilfe meines Problems jetzt schonmal.
#include <stdio.h> #include <stdlib.h> #include <conio.h> #include <ctype.h> #define clrscr() system("cls"); int result; char answer; int zaehler; int i=0; FILE *datei; struct musiktitel { char titelname[16]; char interpret[16]; int dauer; } eingabe[100]; void menue(); void titel_eingeben(); void titel_ausgeben(); void datei_schreiben(); int main(void) { char answer; zaehler=0; do { clrscr(); menue(); int result=getch(); if (result=='1') { zaehler++; titel_eingeben(); } else if (result=='2') { titel_ausgeben(); } else { printf ("Sie haben eine falsche Zahl eingegeben!\n(Bitte korrigieren Sie ihre Eingabe!)\n\n"); } printf("\n"); printf("Sie haben %d Titel eingegeben!(Maximum sind 100)\n\n", zaehler); printf("Moechten sie eine neue Auswahl treffen?(J/N)\n\n"); answer=toupper(getchar()); getchar(); } while (answer=='J'); } void menue() { printf("Musik-Datenbank\n\n" "Musiktitel eingeben 1\n" "Musiktitel ausgeben 2\n\n" "Bitte waehlen Sie\n\n"); } void titel_eingeben(struct musiktitel *tab) { clrscr(); printf("Sie haben sich fuer 'Titel eingeben' entschieden!\n\n"); do { fflush(stdin); printf("Geben sie jetzt zuerst den Titel an!(Maximal 15 Zeichen)\n\n"); gets(eingabe[i].titelname); clrscr(); printf("Titelname:%15s\n\n", eingabe[i].titelname); printf("Jetzt bitte den Interpreten!(Maximal 15 Zeichen)\n\n"); gets(eingabe[i].interpret); clrscr(); printf("Titelname:%15s\n",eingabe[i].titelname); printf("Interpret:%15s\n\n",eingabe[i].interpret); printf("Wie lange dauert der Titel?(Angaben in Sekunden)\n\n"); scanf("%4i",&eingabe[i].dauer); clrscr(); printf("Ihre Angaben waren wie folgt:\n\n"); printf("Titelname:%15s \n",eingabe[i].titelname); printf("Interpret:%15s \n",eingabe[i].interpret); printf("Titellaenge:%13is\n\n",eingabe[i].dauer); printf("Ist das korrekt?(J/N)\n\n"); answer=toupper(getchar()); getchar(); clrscr(); if (answer=='J') { datei_schreiben(); i++; printf("Ihre Angaben wurden gespeichert!\n\n"); } } while (answer=='N'); } void titel_ausgeben(void) { int z; clrscr(); datei=fopen("musik_db.txt","rb"); rewind(datei); printf("\t***********************************************\n"); printf("\t*< Musik-Datenbank >*\n"); printf("\t***********************************************\n"); printf("\t< Titelname <> Interpret <> Dauer >\n"); printf("\t***********************************************\n"); for (z=0;z<i;z++) { fread(eingabe, sizeof eingabe, 1, datei); printf("\t-----------------------------------------------\n"); printf("\t< %-15s %-15s %4is >\n", eingabe[z].titelname, eingabe[z].interpret, eingabe[z].dauer); printf("\t-----------------------------------------------\n"); } fclose(datei); printf("\t***********************************************\n\n"); } void datei_schreiben() { datei=fopen("musik_db.txt","a+b"); fseek(datei, 0 , SEEK_END); fwrite(eingabe, sizeof eingabe, 1, datei); fclose(datei); }
Ming-GW-Compiler
Programm: Eclipse
-
am besten hilft dir beim debuggen der debugger. da siehst du doch dann was passiert.
-
Hallo sn0wi,
ich habe mir mal deinen Code angesehen und ein wenig verbessert.
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #define clrscr() system("clear"); struct musiktitel { char titelname[16]; char interpret[16]; int dauer; }; static void remove_nextline(char *s) { unsigned int i; for (i=0; i<strlen(s); ++i) { if (s[i] == '\n') s[i] = 0; } } static int eingabe_ja(void) { char answer = 0; while (!(answer == 'J' || answer == 'N')) { printf("Eingabe (J/N): "); scanf("%c", &answer); getchar(); answer = toupper(answer); } if (answer == 'J') return 1; return 0; } static void datei_schreiben(struct musiktitel *eingabe) { FILE *datei=fopen("musik_db.txt","a+b"); fseek(datei, 0 , SEEK_END); fwrite(eingabe, sizeof(struct musiktitel), 1, datei); fclose(datei); } static int menue(void) { int result = -1; clrscr(); while (1) { printf("Musik-Datenbank\n\n"); printf("Musiktitel eingeben 1\n"); printf("Musiktitel ausgeben 2\n\n"); printf("Bitte waehlen Sie: "); scanf("%d", &result); getchar(); if (!(result == 1 || result == 2)) { printf("Sie haben eine falsche Zahl eingegeben!\n"); printf("Bitte korrigieren Sie ihre Eingabe: "); } else { break; } } return result; } static void titel_eingeben(void) { struct musiktitel eingabe; char answer; clrscr(); printf("Sie haben sich fuer 'Titel eingeben' entschieden!\n\n"); do { printf("Geben sie jetzt zuerst den Titel an!(Maximal 15 Zeichen)\n\n"); fgets(eingabe.titelname, 15, stdin); remove_nextline(eingabe.titelname); clrscr(); printf("Titelname:%15s\n\n", eingabe.titelname); printf("Jetzt bitte den Interpreten!(Maximal 15 Zeichen)\n\n"); fgets(eingabe.interpret, 15, stdin); remove_nextline(eingabe.interpret); clrscr(); printf("Titelname:%15s\n",eingabe.titelname); printf("Interpret:%15s\n\n",eingabe.interpret); printf("Wie lange dauert der Titel? (Angaben in Sekunden)\n\n"); scanf("%4i",&eingabe.dauer); getchar(); clrscr(); printf("Ihre Angaben waren wie folgt:\n\n"); printf("Titelname:%15s \n",eingabe.titelname); printf("Interpret:%15s \n",eingabe.interpret); printf("Titellaenge:%13is\n\n",eingabe.dauer); printf("Ist das korrekt?\n"); if (eingabe_ja()) { datei_schreiben(&eingabe); printf("Ihre Angaben wurden gespeichert!\n\n"); } } while (answer=='N'); } static void titel_ausgeben(void) { struct musiktitel eingabe; FILE *datei=fopen("musik_db.txt","rb"); clrscr(); rewind(datei); printf("\t***********************************************\n"); printf("\t*< Musik-Datenbank >*\n"); printf("\t***********************************************\n"); printf("\t< Titelname <> Interpret <> Dauer >\n"); printf("\t***********************************************\n"); while (fread(&eingabe, sizeof(struct musiktitel), 1, datei) > 0) { printf("\t-----------------------------------------------\n"); printf("\t< %-15s %-15s %4is >\n", eingabe.titelname, eingabe.interpret, eingabe.dauer); printf("\t-----------------------------------------------\n"); } fclose(datei); printf("\t***********************************************\n\n"); } int main(void) { int eingabe = 0; int zaehler = 0; do { int result; result = menue(); switch (result) { case 1: zaehler++; titel_eingeben(); break; case 2: titel_ausgeben(); break; default: break; } printf("\n"); printf("Sie haben %d Titel eingegeben!\n\n", zaehler); printf("Moechten sie eine neue Auswahl treffen?\n"); eingabe = eingabe_ja(); } while (eingabe); return 0; }
Nun noch ein wenig zu deinen Fehlern:
-- scanf liest das letzte \n nicht mit, daher verwende ich getchar() nach scanf -- gets solltest du nicht mehr verwenden, da es nicht sicher ist. Daher verwende ich fgets(). Diese Funktion liest nun aber das \n mit, daher die Funktion remove_nextline(). -- eingabe_ja() verwende ich nur, weil ich es netter finde. -- fwrite(eingabe, sizeof eingabe, 1, datei), so wie du das verwendet hast, schreibt nicht nur den einen Datensatz, den du neu eingegeben hast, sondern alle 100, weil "sizeof eingabe" so groß war. -- gleicher fehler bei fread. ich habe das dahingehend geändert, dass du jedes mal den aktuellen Datensatz in die Datei schreibst. Nun klappt auch das Auslesen.
So, viel Spaß mit dem korrigierten Code.
Gruß mcr
PS: ich weiß, da sind noch einige Sicherheitsfragen/return codes zu beachten,
aber darum kannst du dich ja kümmern.
-
Mist, ich habe einen kleinen Fehler in meinem Code gefunden.
Zeile 103Aber das schaffst du schon selber, ihn zu beseitigen.
Gruß mcr
-
Zeile 103
Fehler entdeckt, rausgefiltert. ^^
Perfekt.
Vielen lieben Dank.
-
-gelöscht und erledigt-