- Daten werden in Dateien gespeicher
- für Mensch als Text lesbar
- Computer speichert nur Sequenz aus ganz vielen "1" und "0"
- Programme interpretieren diese Sequenz so, dass die Daten für Menschen lesbar sind
- Dateien kann man in Ordnern und Unterordnern speichern
- es gibt einen exakten Pfad
- wichtigste zwei Dateitypen
- Maschinencode
- Die Sprache des Prozessors
- Plaintext
- vom Menschen geschrieben
- "Sourcecode", "Quellcode"
- Textdateien bestehen aus Text ohne Formatierung
- Eine Datei ist eine Sammlung logischer Dateneinheiten
- Dateisysteme speichern z.B. Daten, Code, Programme, etc. dauerhaft in Dateien
- Dateisysteme ermöglichen
- Abstraktion von Hintergrundspeichern, z.B. Platten, CD-ROM, USB, Bandlaufwerke, …
- Einheitliche Schnittstelle
Dateiattribute
- Name: Symbolischer Name, vom Benutzer lesbar und interpretierbar
- Größe: Länge der Datei (Bytes, Blocks, ...)
- Zeitstempel: Zeitpunkt der Erstellung, letzte Modifikation, ...
- Rechte: Zugriffsrechte
- Eigentümer: Identifikation
Beispiel:
manfred% ls -l .
…
drwxr-xr-x 10 manfred user 2048 2021-08-21 12:41 progintro
-rw-r--r-- 1 manfred user 1047 2021-09-16 15:56 hello.c
…
ls -l listet den Inhalt des aktuellen Verzeichnisses auf -> Unix Befehle
- drwxr-xr-x 10 manfred user 2048 2021-08-21 12:41 progintro
- d: das erste Zeichen gibt den Typ der Datei an. Eind d bedeutet directory
- rwx für den Besitzer (manfred) bedeutet: Lesen (r), Schreiben (w), Ausführen/Betreten (x) ist erlaubt.
- r-x für die Gruppe (user) bedeutet: Lesen und Ausführen erlaubt, aber kein Schreiben.
- r-x für andere (world) bedeutet ebenfalls: Lesen und Ausführen erlaubt, aber kein Schreiben.
- 10 Anzahl der backlinks
- manfred: Der Besitzer (owner) der Datei bzw. Verzeichnis
- user Die Gruppe, der diese Datei zugeordnet ist
- 2048: Größe der Datei in Bytes
- 2021-08-21 12:41: modification time
Operationen auf Dateien
- Erzeugen (create)
- Schreiben (write)
- Lesen (read)
- Löschen (delete)
- Öffnen/Schließen einer Datei (open/close)
Verzeichnisse
- Ein Verzeichnis ist eine Sammlung von Dateien und Verzeichnissen
- Verzeichnisattribute: Ähnlich wie Dateiattribute:
- Name, Größe, Datum des letzten Updates, Eigentümer, Rechte
Unix Pfadnamen
- !200
- Benannt sind die Verbindungen zwischen Dateien und Verzeichnissen
- Verschiedene Pfade für dieselbe Datei bzw. dasselbe Verzeichnis möglich
- bei windows mit backslash
\ statt slash /
- Rückverweise: “..“
- Selbstverweise: “.“
- Verschiedene Pfade für dieselbe Datei bzw. dasselbe Verzeichnis möglich
- Aktuelles Verzeichnis:
- /home/manfred/test/
- /home/manfred/test/.
- /home/manfred/test/../test
- wenn am Anfang
/ ist das der absolute Pfad, wenn nicht der relative
- absoluter Pfad bedeutet, dass der komplette Baum von der Wurzel ausgehen abgebildet ist
- Formatierte Ausgabe:
fprintf
- Aufruf:
fprintf(FILE *stream, fmt, args)
fprintf() wie printf jedoch mit Dateien / Streams, d.h. konvertiert und gibt die Parameter args unter Kontrolle des Formatstrings fmt auf stream aus
- Beispiele: // fprintf(stdout, ...) entspricht printf
− fprintf(stdout, “Hello world\n“);
− fprintf(stdout, “Wert von i: %d\n“, i);
− fprintf(stdout, “a(%d)+b(%d) ist: %d\n“, a, b, a+b);
```
- Aufruf:
fscanf(FILE *stream, fmt, args)
fscanf() liest von stream und versucht, die Eingabe unter Kontrolle des Formatstrings fmt auf die Parameter args abzubilden
- Beispiele:
// fscanf(stdin, ...) entspricht scanf− int a, b; fscanf(stdin, “%d %d“, &a, &b);
− float x; fscanf(stdin, “%f“, &x);
− char a; fscanf(stdin, “%c“, &a);
Öffnen von Dateien: fopen
- Aufruf:
FILE *stream fopen(path, mode)
fopen() öffnet die Datei path im Modus mode
- Beispiele:
FILE *file_pointer_in, *file_pointer_out;
// öffnet Datei „datei“ zum Lesen
file_pointer_in = fopen(“./datei“, “r“);
// öffnet „datei“ zum Schreiben
file_pointer_out = fopen(“./datei“, “w“);
// öffnet „datei“ zum Schreiben mittels Anhängen am Dateiende
file_pointer_out = fopen(“./datei“, “a“);
- Wichtig: Immer prüfen, ob fopen erfolgreich war, indem du zum Beispiel
if (fp == NULL) prüfst. Ist es NULL, dann gab es ein Problem beim Öffnen (Datei nicht gefunden, keine Berechtigung, …).
Lesen von Datei – Ausgabe auf stdout
// Konvention: „fp“ kurz für „file_pointer“
FILE *fp = fopen(“datei.txt“, “r“);
int a, b;
if (fp == NULL ) {
perror(“Fehler beim öffnen der Datei“);
return 1; }
while (fscanf(fp, “%d %d\n“, &a, &b) != EOF) {
printf(“%d %d\n“, a, b); }
fclose(fp);
- void perror(msg)
- gibt letzte Systemfehlermeldung auf
stderr aus
Lesen von Datei – Ausgabe von Datei
FILE *fpin = fopen(“datei_in“, „r“);
FILE *fpout = fopen(“datei_out“, „a“);
int a, b;
while (fscanf(fpin, “%d %d\n“, &a, &b) != EOF) {
fprintf(fpout, “%d + %d = %d\n“, a,b,a+b);
}
fclose(fpin); fclose(fpout);
- Hinweis: Fehlerbehandlung fehlt, ist aber notwendig!!!
- Problem: Fehlerhafte Eingabedaten
- Eingabedaten entsprechen nicht unbedingt den Erwartungen
- Z.B. anstelle einer Zahl ein String
- Deshalb immer überprüfen, ob das Lesen erfolgreich war!
- Kann bei scanf, fscanf problematisch sein. Lösung:
- fgets zum Lesen einer Zeile
- gefolgt von sscanf zum Konvertieren des Strings in Token (int, float, etc.)
- Aufruf:
char *fgets(char *buf, int n, FILE *stream)
fgets() liest bis zum ersten Newline „\n“ von stream
- dabei aber maximal n-1 Zeichen, und fügt „\0“ am Ende hinzu oder
- bis EOF
- je nachdem welche Bedingung als erste zutrifft
char buf[200];
int a, b;
char *h = fgets(buf, 200, stdin); // Liest bis zu 199 Zeichen + '\0'
if (h==NULL) {
printf(„error in fgets“);
exit(1);
}
int ret = sscanf(buf, „%d %d“, &a, &b);
if (ret == 2) {
printf(„read 2 integers: %d %d\n“, a, b);
} else {
fprintf(stderr, „error reading 2 integers\n“);
}
- Finger weg von
gets(char *buf) !!! gets liest unabhängig von der Größe des Buffers bis zum ersten Newline „\n“ von stream. Gefahr eines “Buffer Overflow“ !!!
- Sicherheitslücke, weil man so auf den kompletten Speicher zugreifen kann