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;
}