Kapitel 7 Unit 33 von 36 Theorie + Übungen Dauer: ~100 Min.
Ömer
Ömer sagt:

Jetzt arbeiten wir mit echten Dateien! Du lernst wie man mit fopen, fprintf und fscanf Daten dauerhaft auf der Festplatte speichert und wieder einliest. Das ist ein riesiger Schritt – Daten überleben jetzt das Programmende!

Datei-Modi kennen fopen und fclose anwenden NULL-Check schreiben fprintf und fscanf nutzen Append-Modus verstehen Fehler in Datei-Code erkennen
Übung 1

Modi kennen – Welcher Modus passt?

Trage in der rechten Spalte den richtigen fopen-Modus ein ("r", "w", "a" oder "r+"):

#SituationRichtiger Modus
1 Du möchtest eine neue Konfigurationsdatei anlegen und Werte hineinschreiben. Eine alte Version darf überschrieben werden.  
2 Du möchtest eine bestehende Textdatei einlesen und die Daten verarbeiten. Die Datei darf nicht verändert werden.  
3 Jedes Mal wenn dein Programm startet, soll ein neuer Eintrag ans Ende der Log-Datei angefügt werden, ohne alte Einträge zu löschen.  
4 Du möchtest eine bereits existierende Datei sowohl lesen als auch an beliebigen Stellen bearbeiten.  
5 Du möchtest eine CSV-Datei mit Schüler-Noten von der Festplatte einlesen und auswerten. Die Datei wird nur gelesen.  
Die vier Modi: "r" = nur lesen, "w" = neu schreiben (überschreibt!), "a" = anhängen, "r+" = lesen und schreiben.
Übung 2

Datei schreiben – Schüler-Datei anlegen

Vervollständige das Programm: Es soll deinen Namen und drei Noten in die Datei schueler.txt schreiben. Fülle alle markierten Lücken (???) aus.

#include <stdio.h> int main() { char name[] = "Anna Muster"; int noten[] = {1, 2, 3}; /* 1. Datei öffnen – Modus zum Schreiben */ FILE *f = fopen("schueler.txt", ???); /* 2. NULL-Check */ if (???) { printf("Fehler beim Öffnen!\n"); return 1; } /* 3. Name in Datei schreiben */ fprintf(???, "Name: %s\n", name); /* 4. Noten schreiben (Schleife) */ for (int i = 0; i < 3; i++) { fprintf(???, "Note %d: %d\n", i+1, noten[i]); } /* 5. Datei schließen */ ???; printf("schueler.txt erfolgreich gespeichert.\n"); return 0; }

Was steht nach dem Programmlauf in schueler.txt? Schreibe den erwarteten Inhalt hier auf:

Denk daran: der erste Parameter von fprintf ist der FILE-Pointer, nicht stdout!
Übung 3

Datei lesen – schueler.txt einlesen

Schreibe ein Programm das die Datei schueler.txt aus Übung 2 einliest und den Inhalt Zeile für Zeile auf der Konsole ausgibt. Nutze fgets zum zeilenweisen Lesen.

#include <stdio.h> int main() { FILE *f = fopen("schueler.txt", ___); if (___) { printf("Fehler: Datei nicht gefunden!\n"); return 1; } char zeile[256]; /* Puffer fuer eine Zeile */ printf("Inhalt von schueler.txt:\n"); printf("------------------------\n"); /* Zeile fuer Zeile lesen, bis Dateiende */ while (___(zeile, 256, f) != NULL) { printf("%s", zeile); } /* Datei schliessen */ ___; return 0; }

Welche Ausgabe erwartest du auf der Konsole?

fgets(puffer, groesse, datei) liest eine ganze Zeile inklusive dem Zeilenumbruch \n in den Puffer. Gibt NULL zurück wenn das Dateiende erreicht ist.
Übung 4

Programm schreiben – Digitales Tagebuch

Schreibe ein vollständiges Programm für ein einfaches digitales Tagebuch:

Tipp: Schritt für Schritt – erst nur Anhängen ohne Zähler lösen, dann den Zähler ergänzen.

#include <stdio.h> int main() { /* Schritt 1: Zaehler aus zaehler.txt lesen */ int zaehler = 1; FILE *z = fopen("zaehler.txt", "r"); if (z != NULL) { fscanf(z, "%d", &zaehler); fclose(z); } /* Schritt 2: Eintrag in tagebuch.txt anhaengen */ /* Dein Code hier: */ /* Schritt 3: Zaehler erhoehen und zurueckschreiben */ zaehler++; /* Dein Code hier: */ printf("Eintrag %d wurde gespeichert.\n", zaehler - 1); return 0; }

Was steht in tagebuch.txt nach dem dritten Programmstart?

Append-Modus "a": Die Datei wird nicht gelöscht, neuer Inhalt kommt immer ans Ende. Perfekt für Log-Dateien und Tagebücher!
Übung 5

Fehler korrigieren – 3 Bugs im Code

Das folgende Programm enthält 3 Fehler. Finde und markiere sie, dann schreibe die korrigierte Version darunter.

fehlerhaft.cC (fehlerhaft)
#include <stdio.h>

int main() {
    int zahl;

    /* Datei zum LESEN öffnen */
    FILE *f = fopen("daten.txt", "w");  /* Fehler 1 */

    /* Direkt verwenden ohne Prüfung */
    fscanf(f, "%d", &zahl);           /* Fehler 2 */
    printf("Gelesen: %d\n", zahl);

    /* Programm endet hier ohne fclose */
    return 0;                             /* Fehler 3 */
}

Beschreibe die drei Fehler:

Fehler 1:

Fehler 2:

Fehler 3:

Schreibe das korrigierte Programm:

#include <stdio.h> int main() { int zahl; /* Dein korrigierter Code: */ return 0; }
Die drei häufigsten Datei-Fehler: falscher Modus, fehlender NULL-Check nach fopen, fehlendes fclose am Ende.
Bonus – CSV-Reader

Noten aus einer CSV-Datei lesen und auswerten

Eine Datei noten.csv enthält Zeilen im Format:

noten.csvCSV
Anna,1,2,3
Ben,2,3,2
Clara,1,1,2
David,3,4,3

Schreibe ein C-Programm das:

  1. Die Datei noten.csv öffnet und zeilenweise einliest
  2. Für jede Zeile: Namen und drei Noten mit sscanf oder durch Parsen trennt
  3. Den Notendurchschnitt je Schüler berechnet und ausgibt
  4. Am Ende den besten Schüler (niedrigster Durchschnitt) nennt

Hinweis: Nutze fgets zum Zeilenlesen und sscanf(zeile, "%[^,],%d,%d,%d", name, &n1, &n2, &n3) zum Parsen.

#include <stdio.h> #include <string.h> int main() { FILE *f = fopen("noten.csv", "r"); if (f == NULL) { printf("Fehler: noten.csv nicht gefunden!\n"); return 1; } char zeile[256]; char name[64]; int n1, n2, n3; char bester_name[64] = ""; float bester_schnitt = 999.0f; while (fgets(zeile, 256, f) != NULL) { /* Zeile parsen: "Name,Note1,Note2,Note3" */ if (sscanf(zeile, "%63[^,],%d,%d,%d", name, &n1, &n2, &n3) == 4) { float schnitt = (n1 + n2 + n3) / 3.0f; printf("%-10s Schnitt: %.2f\n", name, schnitt); /* Besten Schueler merken */ if (schnitt < bester_schnitt) { bester_schnitt = schnitt; /* Dein Code: Namen kopieren */ } } } fclose(f); /* Dein Code: Besten Schueler ausgeben */ return 0; }

Welche Ausgabe erwartest du für die Beispiel-CSV?

Der Formatstring "%63[^,]" liest alle Zeichen bis zum ersten Komma in den Namen-Puffer. Das ist ein nützlicher Trick für CSV-Parsing in C!

Reflexion

Was ich in Unit 33 gelernt habe

Beantworte kurz in eigenen Worten:

1. Warum ist fclose() so wichtig?

2. Was passiert wenn ich den NULL-Check nach fopen() weglasse und die Datei nicht existiert?

3. Wann würdest du Modus "a" statt "w" verwenden? Nenne ein eigenes Beispiel.