fseek() - Verständnisproblem
-
Zu deinem Problem: lese alle Einträge in dein Programm ein. Manipuliere im Speicher deine Einträge und schreibe diese anschließend in die Datei.
Ansonsten solltest du die Programmlogik und Datenhaltung voneinander trennen. Verwende doch eine Datenbank-Bibliothek, wie die "Berkeley DB" oder SQLite. Oder nutze das Dateisystem und schreibe eine Datei pro Eintrag. Alle Einträge findest du dann durch Iteration des Verzeichnisinhalts.
-
f.-th. hatte oben einen Link mit einem Beispiel gepostet.
Allerdings wird der Modus "a" immer dafür sorgen, dass Inhalt am Ende angehängt wird. Wenn Du in der selben Datei, an der Du anhängen möchtest den Filepointer positionieren willst, musst Du "a+" verwenden. Dennoch wird nicht an der Position des File-Pointers, sondern am Ende der Datei angefügt, wenn Du schreibst.
Ich kenne im Grunde nur diese Möglichkeit, die bereits beschrieben wurde: die Datei1 auslesen und Datei2 beschreiben, bis die passende Position erreicht ist, dann den Satz einfügen und wiederum Datei1 auslesen und Datei2 beschreiben, bis Datei1 am Ende ist.
-
Danke euch!
B3rnDi, deine Version verstehe ich ok.
Sorry, Ein C-Progger, aber von solchen Datenbanken hab ich noch nie gehört und ich habe keine blassen Schimmer davon, da wir sowas noch nicht lernten.
Aber kennt den niemand eine lösung mit fseek? In meinem Programm oben habe ich ja fseek verwendet und es setzt den Cursor genau dorthin wo der Termin eingeschoben werden soll, aber wie es weiter geht weis ich halt nicht.
-
Lies dir noch mal die Bedeutung von den verschidenen Modi von fopen durch: http://www.cplusplus.com/reference/clibrary/cstdio/fopen/
Du hast die falschen benutzt.Einfügen kannst du aber nicht mit fseek, nur überschreiben.
-
Danke habe ich gar net so beachtet
Ich habs jetzt programmiert theoretisch müsste es so funktionieren glaube ich aber es kommt ein fatal error. Fatal error treten doch auch auf wenn man ein Unterprogramm aufruft, aber es keins gibt oder so... Ist aber nicht so in meinem Fall.
1>LINK : fatal error LNK1168: "Debug\termin_original.exe" kann nicht zum Schreiben geöffnet werden.
Hier mal das Unterprogramm vielleicht könnt ihr herausfinden wo der error liegt, ansonsten sagt es wenn ich das ganze Programm posten soll:
termin* termin_einfügen(char filename[]) { FILE* inFile=NULL; termin* all_termin=NULL; termin termine; termin* temp = NULL; int len=0; int termin_zahl=0; int byte_anz=0; int hilf=0; sprintf(termine.thema ,"unser eingeschobener termin"); strcpy(termine.beschreibung ,"gibts keine"); strcpy(termine.teilnehmer ,"ich bin alleine"); termine.von.jahr = 2012; termine.von.mon = 2; termine.von.tag = 28; termine.status = OFFEN; termine.priority = 1; inFile=fopen(filename,"r+b"); if(inFile == NULL) { printf("Die datei %s konnte nicht geöffnet werden",filename); exit(-1); } fseek(inFile,0L,SEEK_END); len=ftell(inFile)/sizeof(termin); temp=(termin *)malloc(sizeof(termin)*len); if(temp != NULL) { printf("Geben Sie die Zahl des Termins ein, wo dann Ihr neuer Termin eingefügt werden soll:"); scanf("%d",&termin_zahl); hilf=len-termin_zahl; byte_anz=sizeof(termin)*termin_zahl; fseek(inFile,byte_anz,SEEK_SET); fread(temp,sizeof(termin),hilf,inFile); fwrite(&termine,sizeof(termin),1,inFile); fseek(inFile,sizeof(termin),SEEK_CUR); fwrite(temp,sizeof(termin),hilf,inFile); } else { printf("Memory allocation failure!"); } return(temp); }
-
Das ist kein Fehler von deinem Programm sondern vom Linker.
Die Datei "Debug\termin_original.exe" ist gerade schreibgeschützt.
Das kommt davon, dass noch eine Instanz von deinem Programm läuft (ein Fenster mit deinem Programm ist noch offen).
-
Ok, danke jetzt hab ichs.
Die nächste Aufgabe ist einen bestimmten Termin suchen im Binärfile und dann auslesen.
Meine Idee: Ich geben vorher das Datum ein und dann vergleiche ich das Datum mit den Datums im Binärfile wenn die gleich sind speichere ich sie in eine Adresse wo ein Pointer draufzeigt, da es ja mehrere Termine an einem Tag geben kann. Problem ist nur das ich 2mal fast den selben Vorgang mache und das ist nicht gut.Hier mal der Ausschnitt:
termin* termin_einfügen(char filename[]) { FILE* inFile=NULL; termin* all_termin=NULL; termin termine; termin* temp = NULL; int len=0; int termin_zahl=0; int byte_anz=0; int hilf=0; int strukt=0; sprintf(termine.thema ,"unser eingeschobener termin"); strcpy(termine.beschreibung ,"gibts keine"); strcpy(termine.teilnehmer ,"ich bin alleine"); termine.von.jahr = 2012; termine.von.mon = 2; termine.von.tag = 28; termine.status = OFFEN; termine.priority = 1; inFile=fopen(filename,"r+b"); if(inFile == NULL) { printf("Die datei %s konnte nicht geöffnet werden",filename); exit(-1); } fseek(inFile,0L,SEEK_END); len=ftell(inFile)/sizeof(termin); temp=(termin *)malloc(sizeof(termin)*len); if(temp != NULL) { printf("Geben Sie die Zahl des Termins ein, wo dann Ihr neuer Termin eingefügt werden soll:"); scanf("%d",&termin_zahl); hilf=len-termin_zahl; strukt=sizeof(termin); byte_anz=sizeof(termin)*termin_zahl; fseek(inFile,byte_anz,SEEK_SET); fread(temp,sizeof(termin),hilf,inFile); rewind(inFile); fseek(inFile,byte_anz,SEEK_SET); fwrite(&termine,sizeof(termin),1,inFile); fwrite(temp,sizeof(termin),hilf,inFile); } else { printf("Memory allocation failure!"); } return(temp); }
Hier die lange Struktur:
struct timestamp_struct { short jahr; short mon; short tag; int min; }; typedef struct timestamp_struct timestamp; struct termin_struct { char thema[MAX_THEMALEN]; timestamp von; timestamp bis; char teilnehmer[MAX_TEILNEHMER]; short priority; char beschreibung[MAX_BESCHR]; short status; }; typedef struct termin_struct termin;
Natürlich könnte ich die gesuchten Termine auch gleich im Unterprogramm ausgeben, aber zum Ausgeben habe ich eine weitere Funktion, die ich dann im Hauptprogramm aufrufen werde.
Diese sieht so aus:
void termin_out(termin termin_zur_ausgabe) { printf("------------------\n"); printf("Termin: %s \nTeilnehmer %s \nprio %d \nBeschreibung: %s \nStatus %d\n",termin_zur_ausgabe.thema,termin_zur_ausgabe.teilnehmer,termin_zur_ausgabe.priority,termin_zur_ausgabe.beschreibung,termin_zur_ausgabe.status); printf("------------------\n"); }
Naja wie könnte ich das nun Verbessern?
-
Oh sorry, das ist der falsche Ausschnitt.
Den meine ich:
termin* termin_search(char filename[]) { FILE* outFile=NULL; termin temp; timestamp dat_von; termin* term_gesucht=NULL; int anz=0; outFile=fopen(filename,"r+b"); if(outFile == NULL) { printf("File %s could not be opened!",filename); exit(-1); } printf("Geben Sie das Datum des/der gesuchten Termin(e) ein(TTMMJJ):"); scanf("%d",dat_von.tag); scanf("%d",dat_von.mon); scanf("%d",dat_von.jahr); while(!feof(outFile)) { fread(&temp,sizeof(termin),1,outFile); if(temp.von.tag == dat_von.tag && temp.von.mon == dat_von.mon && temp.von.jahr == dat_von.jahr) { anz++; } } rewind(outFile); term_gesucht=malloc(sizeof(termin)*anz); while(!feof(outFile)) { fread(&temp,sizeof(termin),1,outFile); if(temp.von.tag == dat_von.tag && temp.von.mon == dat_von.mon && temp.von.jahr == dat_von.jahr) { term_gesucht=temp; term_gesucht++; } } return(term_gesucht); }
-
Statt
sparrow12 schrieb:
while(!feof(outFile)) { fread(&temp,sizeof(termin),1,outFile);
ist viel einfacher und sicherer
while( 1==fread(&temp,sizeof(termin),1,outFile) ) { ;
da hierbei nur vollständig gelesene Strukturblöcke berücksichtigt werden.
-
Danke!
Ich habs jetzt geschafft das ich nur eine Schleife brauche, glaube ich :).
Siehe comments pls.void termin_search(char filename[]) { FILE* outFile=NULL; termin temp; timestamp dat_von = {0,0,0,0}; outFile=fopen(filename,"rb"); if(outFile == NULL) { printf("File %s could not be opened!",filename); exit(-1); } printf("Geben Sie das Datum des/der gesuchten Termin(e) ein(TTMMJJ):"); scanf("%d",&dat_von.tag);//wenn ich hier z.B. 26 eingebe scanf("%d",&dat_von.mon);//und dann hier 2, dann steht in dat_von.tag plötzlich 0 scanf("%d",&dat_von.jahr);//wenn ich hier 2012 eingebe, dann steht in dat_von.mon auch 0, aber jahr 2012 bleibt erhalten while(1 == fread(&temp,sizeof(termin),1,outFile)) { if(temp.von.tag == dat_von.tag && temp.von.mon == dat_von.mon && temp.von.jahr == dat_von.jahr) { termin_out(temp); } } }
Warum ist das so? Ich finde keine Fehler
.
-
sparrow12 schrieb:
scanf("%d",&dat_von.tag);//wenn ich hier z.B. 26 eingebe scanf("%d",&dat_von.mon);//und dann hier 2, dann steht in dat_von.tag plötzlich 0 scanf("%d",&dat_von.jahr);//wenn ich hier 2012 eingebe, dann steht in dat_von.mon auch 0, aber jahr 2012 bleibt erhalten
Warum ist das so? Ich finde keine Fehler
.
Das liegt daran, dass du dein Programm hier falsch entworfen hast, du verlangst von Nutzer EINE Eingabe ("TTMMJJ"), im Code verwendest du aber 3 Eingabefunktionen (die jeweils eine Eingabe erwarten), also besser (und viel einfacher):
if( 3==scanf("%02d%02d%02d",&tag,&monat,&jahr) ) { } while( '\n'!=getchar() );
-
Wenn du dir mal deine timestamp_struct ansiehst
struct timestamp_struct { short jahr; short mon; short tag; int min; };
kannst du erkennen, dass jahr, monat und tag vom typ short sind.
%d ist bei scanf aber für ein int da.
Also nochmal die Doku für scanf durchlesen, wie man ein short einliest.
Dafür gibt es keinen eigenen Typ sondern einen Modifier.
Das ergibt dann %hd