// C-Programmierung Beleg 5 // Copyright: Matthias Jauernig, 2004 #include #include #include #include #include // WICHTIG!: laut C9X-Standard ist fflush() nur auf Output-Streams anwendbar, // fflush(stdin) z.B. undefiniert - dass dies bei Solaris funktioniert, ist reiner Zufall, // bei Linux und anderen Systemen kann das schon ganz anders aussehen... // => daher: eigenes Fflush() als Makro realisieren, welches stdin flush'ed #define Fflush() while(getchar() != '\n') /* --- Datenstruktur -------------------------------------------------------------------------- */ typedef struct { char name[30], vorname[20]; char adresse[50]; } datensatz; /* --- Funktionsdeklarationen ----------------------------------------------------------------- */ bool eingabe(char *filename); bool ausgabe(char *filename); bool aendern(char *filename); /* --- main() --------------------------------------------------------------------------------- */ int main(int argc, char **argv){ //argv[1] ist evtl. filename char abfrage='j', *filename=(char*)malloc(100); FILE *fp; bool retval; do{ if(argc==1 || abfrage!='j'){ printf("\nEinzulesende Datei angeben: "); scanf("%s", filename); Fflush(); } else strncpy(filename, argv[1], 100); //filenamen lesen fp=fopen(filename,"rb"); //File existent? if(!fp){ //Datei existiert nicht perror("Fehler"); printf("Datei neu anlegen (j/n, q=quit)?: "); abfrage=getchar(); Fflush(); if(abfrage=='J' || abfrage=='j') fp=fopen(filename,"ab"); //File anlegen (Append-Modus) else if(abfrage=='q' || abfrage=='Q') return 1; //Quit } else abfrage='j'; //Datei existiert, daher weiter }while(abfrage!='j' && abfrage!='J'); fclose(fp); do{ printf("\n-------------\n" "| Hauptmenu |\n" "-------------\n"); printf("(1) Eingabe eines Datensatzes\n" "(2) Ausgabe der Datensaetze im File\n" "(3) Datensatz aendern\n" "(4) Verlassen\n" "> "); abfrage=getchar(); Fflush(); retval=true; switch(abfrage){ case '1': retval=eingabe(filename); break; case '2': retval=ausgabe(filename); break; case '3': retval=aendern(filename); break; case '4': break; default: printf("Ungueltige Nummer!\n"); } if(!retval) perror("Fehler"); }while(abfrage!='4'); return 0; } /* --- Funktionsdefinitionen ------------------------------------------------------------------ */ bool eingabe(char *filename){ datensatz neu; FILE *fp=fopen(filename, "ab"); //Schreiben im Append-Modus if(!fp) return false; printf("Name eingeben: "); fgets(neu.name,30,stdin); neu.name[strlen(neu.name)-1]='\0'; printf("Vorname eingeben: "); fgets(neu.vorname,20,stdin); neu.vorname[strlen(neu.vorname)-1]='\0'; printf("Adresse eingeben: "); fgets(neu.adresse,50,stdin); neu.adresse[strlen(neu.adresse)-1]='\0'; if(!fwrite(&neu,sizeof(neu),1,fp)){ fclose(fp); return false; } fclose(fp); return true; } bool ausgabe(char *filename){ int i=1; datensatz neu; FILE *fp=fopen(filename, "rb"); //Lesen im Lese-Modus if(!fp) return false; while(fread(&neu,sizeof(neu),1,fp)){ printf("\nDatensatz Nr. %d:\n",i++); printf("Name: %s\n",neu.name); printf("Vorname: %s\n",neu.vorname); printf("Adresse: %s\n",neu.adresse); } if(ferror(fp)){ fclose(fp); return false; } fclose(fp); return true; } bool aendern(char *filename){ int i, nr; char abfrage, zk[50]; datensatz neu; FILE *fp=fopen(filename, "rb+"); //R/W im Update-Modus if(!fp) return false; printf("\nNr. des zu aendernden Datensatzes?: "); scanf("%d",&nr); Fflush(); if(fseek(fp,0,SEEK_END)==-1){ //Dateiende lesen fclose(fp); return false; } i=ftell(fp); //Bytes bis zur akt. Filepos if(i/sizeof(datensatz) Soll dieser Datensatz wirklich geaendert werden (j/n)?: "); abfrage=getchar(); Fflush(); if(abfrage!='j' && abfrage!='J'){ fclose(fp); return true; } printf("Name eingeben: "); fgets(zk,30,stdin); zk[strlen(zk)-1]='\0'; if(strcmp(zk,"")!=0) strncpy(neu.name,zk,30); printf("Vorname eingeben: "); fgets(zk,20,stdin); zk[strlen(zk)-1]='\0'; if(strcmp(zk,"")!=0) strncpy(neu.vorname,zk,20); printf("Adresse eingeben: "); fgets(zk,50,stdin); zk[strlen(zk)-1]='\0'; if(strcmp(zk,"")!=0) strncpy(neu.adresse,zk,50); if(fseek(fp,-sizeof(neu),SEEK_CUR)==-1){ //einen Datensatz zurück spulen fclose(fp); return false; } if(!fwrite(&neu,sizeof(neu),1,fp)){ fclose(fp); return false; } fclose(fp); return true; }