Informatik - Übungen zu C - File Update
/* fileupdate.c Oft wird gefragt, wie man von einer Text-Datei eine bestimmte Zeile lesen kann, und diese Zeile in veraenderter Form wieder auf die Datei ausgeben kann. Man kann zwar auch eine Textdatei im Modus r+ oeffnen (das erlaubt lesen und schreiben auf die Datei), das funktioniert bedingt jedoch nur, wenn die einzelnen Zeilen immer die gleiche Laenge haben. Der r+ Modus wird fuer Textdateien meist nur verwendet, um am Ende der Datei neue Inhalte anzuhaengen! Zwei Loesungen sind moeglich: 1) Datei zum Lesen oeffnen Die ganze Datei in eine geeignete Datenstruktur lesen. Datei schliessen Inhalte der Datenstruktur aendern Datei zum Schreiben oeffnen die Daten wieder auf die Datei schreiben Datei schliessen 2) Die Originaldatei (D1) oeffnen (Mode "r") eine zweite Datei (D2) oeffnen (Mode "w") Fuer alle Zeilen (Datensaetze) Zeile aus D1 lesen Zeile eventuell veraendern Zeile auf D2 schreiben Dateien schliessen Datei D1 loeschen ( Bibliotheksfunktion: remove ) Datei D2 auf den Namen von D1 umbenennen ( Bibliotheksfunktion: rename ) Im folgenden ist die Loesung 2 ausgefuehrt! Beispiel fuer die vom Programm verwendete Datei mit einem ; als Trennzeichen ------------------------------------------------- 1;Hammer 250 g;60.30 2;Zange;23 3;Draht 2 mm; 12.40 6;Heugabel; 230.50 ------------------------------------------------- */ #include <stdio.h> #include#include #include void datensatz_aendern(unsigned int *nr, char *text, double *preis) { char antwort[10]; /* Der Wechsel zwischen dem Lesen von Zeichenketten und Zahlen erfordert, dass jeweils das von der Eingabetaste erzeugte Zeichen aus dem Buffer entfernt wird, dafuer sorgt das %*c und das %s im Zusammenhang mit der Zeichenkette antwort ! Siehe dazu auch die Seiten 102 und 102 im Buch (4. Aufl.) */ printf("\nArtikelNr. : %-40u Aendern ja/nein ? ", *nr); scanf("%s", antwort); if (tolower(antwort[0]) == 'j') { printf("neue Nummer. : "); scanf("%u%*c", nr); } printf( "ArtikelBez. : %-40s Aendern ja/nein ? ", text); scanf("%s%*c", antwort); if (tolower(antwort[0]) == 'j') { printf("neue Bez. : "); gets(text); } printf( "ArtikelPreis.: %-40.2f Aendern ja/nein ? ", *preis); scanf("%s%*c", antwort); if (tolower(antwort[0]) == 'j') { printf("neuer Preis : "); scanf("%lf%*c", preis); } printf("=================================\n"); } /* end datensatz_aendern */ int main(void) { FILE *fin, *fout; char line[100]; int result; unsigned int artikel_nr; // fortgeschrittene Programmierer char artikel_bezeichnung[40]; // wuerden diesen Datensatz in double artikel_preis; // einer Struktur zusammenfassen unsigned int ges_artikel_nr; if ((fin = fopen("artikel.txt", "r")) == NULL) { printf("Datei konnte nicht geoeffnet werden!\n"); exit(1); } printf("Gesuchte Artikelnr: "); scanf("%u%*c", &ges_artikel_nr); printf("-----------------------------------\n"); fout = fopen("artikelneu.txt", "w"); while (fgets(line, 100, fin)) { /* Zeile durch sscanf zerlegen und zur Kontrolle ausgeben */ result = sscanf(line, "%u;%[^;];%lf", &artikel_nr, artikel_bezeichnung, &artikel_preis); fprintf(stdout, "%08u;%-40s;%8.2f\n", artikel_nr, artikel_bezeichnung, artikel_preis); /* Information ausgeben, wenn die Zerlegung nicht erfolgreich war */ if (result != 3) printf("*** Fehler im letzten Datensatz ***\n"); if (ges_artikel_nr == artikel_nr) { datensatz_aendern(&artikel_nr, artikel_bezeichnung, &artikel_preis); /* veraenderten Datensatz auf Datei schreiben */ fprintf(fout, "%08u;%s;%8.2f\n", artikel_nr, artikel_bezeichnung, artikel_preis); } else /* Datensatz wie gelesen wieder auf Datei schreiben */ fputs(line, fout); } /* end while */ /* hier koennte man zusaetzliche neue Datensaetze auf fout schreiben */ fclose(fin); fclose(fout); /* Nach erfolgreichem Test kann die neue Datei wieder unter dem urspruenglichen Namen gespeichert werden */ remove("artikel.txt"); rename("artikelneu.txt", "artikel.txt"); return 0; }