#36 Dateioperationen Flashcards
Was ist das Ziel von Dateioperationen?
-Ziel: Speichern von Daten in Dateien und Einlesen von Daten aus Dateien
auf Datenträgern.
Welche Zusätzliche Funktion gibt es bei Dateioperationen?
Zusätzliche Funktionen für Binärdateien sowie systemnahe
(low-level) Funktionen
Was ist das Konzept einer Datei?
Jede Datei ist eine Folge von Zeichen
Nenne die Drei Phasen des Dateizugriffs
- Öffnen bzw. Erzeugen der Datei
- Lese- bzw. Schreibzugriffe
- Schließen der Datei
nenne die Funktion zum öffnen einer Dateie.(Syntax)
Wofür stehen die Parameter?
FILE *fopen(const char *fname, const char *mode)
- fname: Dateiname (inklusive Pfad)
- mode: Zeichenkette für Bearbeitungsmodus
- “r”: Öffnen zum Lesen
- “w”: Öffnen zum Schreiben (löscht bestehende Datei mit gleichem Namen)
- “a”: Öffnen zum Schreiben (anhängen, wenn Datei bereits vorhanden)
- “r+”: Öffnen bestehender Datei zum Verändern (lesen und schreiben)
- “w+”: Erzeugen neuer Datei zum Verändern (lesen und schreiben,
löscht vorhandene gleichnamige Datei) - “a+”: Öffnen einer Datei zum Ändern am Ende
Welche Zusätze an mode-String gibt es was machen sie?
- Binärdateien
- Anhängen von b an mode-String
- Daten werden unverändert geschrieben
- Textdateien
- Anhängen von t an mode-String
- es werden systemabhängige Konvertierungen vorgenommen, um (Menschen-)Lesbarkeit und
Portabilität zu erhöhen - Rückgabewert: Zeiger FILE*
- Identifikator für die geöffnete Datei, NULL bei Fehler
- Wird für Schreib-/Lesebefehle benötigt
Welche Befehle haben wir für den Dateizugriff?
- Befehle analog zu Bildschirm-Ein-/Ausgabe
- int putc(int c, FILE *f)
- int getc(FILE *f):
- int fprintf(FILE *f, const char *format, …)
- int fscanf(FILE *f, const char *format, …) - Eingabefunktionen liefern bei Dateiende EOF.
Welcher Befehl dient zum Schließen einer Datei? was sind die Besonderheiten.
- int fclose(FILE *f)
- Noch nicht geschriebene Daten aus dem Puffer werden gespeichert
(zur Steigerung der Performance werden nicht alle Daten sofort geschrieben) - Danach kein Zugriff mehr möglich
Was ist bei der Bildschirm- und Datei-Ein-/Ausgabe zu beachten um Verwechslungen der Meldungen zu vermeiden?
Kein prinzipieller Unterschied zwischen Bildschirm- und Datei-Ein-/Ausgabe
- stdin: Standardeingabekanal
- stdout: Standardausgabekanal
- stderr: Standardfehlerkanal
- Fehler sollten daher möglichst nicht per printf sondern mit
fprintf(stderr, Fehlermeldung) ausgegeben werden.
_________________________________________________________________
Bsp: SpEICHERN
#include<stdio.h>
#include<stdlib.h>
int main()
{
FILE *f = fopen("test.txt", "wt");
if(f == NULL)
{
fprintf(stderr, "Fehler beim Oeffnen der Datei!\n");
exit(EXIT_FAILURE);
}
fprintf(f, "Speichere vier: %d\n", 4);
fclose(f);</stdlib.h></stdio.h>
return 0; } \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_ Bsp:LESEN #include<stdio.h> #include<stdlib.h> int main() { FILE *f = fopen("test.txt", "rt"); if(f == NULL) { fprintf(stderr, "Fehler beim Oeffnen der Datei!\n"); exit(EXIT_FAILURE); } int c; while(EOF != (c = getc(f))) { printf("Gelesenes Zeichen: %c\n", c); } fclose(f); return 0; }
Worin unterscheiden sich puts() und fputs()?
int puts(char *s);
- schreibt die Zeichenkette s und einen nachfolgenden Zeilenumbruch auf den Bildschirm
- Rückgabewert: EOF bei Fehler, nichtnegativ sonst
int fputs(const char *s, FILE *stream);
- schreibt die Zeichenkette s ohne das Abschlusszeichen ‘\0’ in eine Datei
- Rückgabewert: EOF bei Fehler, nichtnegativ sonst
Welche Möglichkeit bietet uns fgets() im bereich des Dateizugriffs?
char *fgets(char *s, int size, FILE *stream);
- fgets liest bis zum nächsten Zeilenwechsel oder EOF, maximal aber size-1
Zeichen, aus einer Datei, speichert sie in einer Zeichenkette und hängt \0 an
(\n wird nicht durch \0 ersetzt).
char s[10];
int i;
printf(“Text eingeben: “);
fgets(s, 10, stdin);
/* Zeilenumbruch entfernen /
char p = strchr(s, ‘\n’);
if(p) {
*p = 0;
}
printf(“Eingegeben wurde "%s"\n”, s);
Was sind wichtige Funktionen zum Steuern des Dateizugriffs?
int fflush(FILE *f): Leeren des Dateipuffers
- void rewind(FILE *f): Setzen der aktuellen Position an den Dateianfang
- long ftell(FILE *f): liefert aktuelle Position des Satzzeigers
- int fseek(FILE *f, long offset, int origin)
- Setzen der Position an beliebige Stelle
- evtl. Probleme bei Textdateien
- offset: Entfernung bzgl. origin, kann auch negativ sein
- origin:
- SEEK_SET: Anfang der Datei
- SEEK_CUR: aktuelle Position
- SEEK_END: Ende der Datei
Bsp:
Auslesen der Dateilänge, danach am Anfang weiterarbeiten
FILE f;
long int dateigroesse;
f = fopen(“test.txt”, “rt”);
if(f == NULL)
{
fprintf(stderr, “Fehler beim Oeffnen der Datei!\n”);
exit(EXIT_FAILURE);
}
/ Springe an Dateiende /
fseek(f, 0, SEEK_END);
/ Lese aktuelle Position /
dateigroesse = ftell(f);
/ Springe an Anfang */
rewind(f);
Was sind die Vorteile von Binärdateien zu Normalen Dateien?
Bisher: Schreiben/Lesen von Texten in/aus Dateien
- Vorteil: Auch mit einem Texteditor editierter
- Nachteil: große Dateien, Daten können unerwünscht geändert werden
- Jetzt: Binärdateien
- C erlaubt es, Daten byteweise in eine Datei zu schreiben
Vergleich Text vs Binär
__________________________________________________________________________________
float a[] = {191232.12, 1293.12, -93991.5, 12921, 53312};
FILE* file = fopen(“a.txt”, “wt”);
if(file == NULL) {
return 1;
}
for(int i = 0; i < 5; i++) {
fprintf(file, “%f\n”, a[i]);
}
fclose(file);
________________________________________________________________________________________
|
|
V
__________________________________________________________________________________________
191232.125000
1293.119995
-93991.500000
12921.000000
53312.000000
66 bytes (größer, leicht editierbar)
__________________________________________________________________________________________
__________________________________________________________________________________________
float a[] = {191232.12, 1293.12, -93991.5, 12921, 53312};
FILE* file = fopen(“b.dat”, “wb”);
if(file == NULL) {
return 1;
}
fwrite(a, sizeof(float), 5, file);
fclose(file);
__________________________________________________________________________________________
|
|
V
__________________________________________________________________________________________
Offset: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00000000: 08 C0 3A 48 D7 A3 A1 44 C0 93 B7 C7 00 E4 49 46 .@:HW#!D@.7G.dIF
00000010: 00 40 50 47
20 bytes (kleiner, aber kaum editierbar)
__________________________________________________________________________________________
Welche Funktionen stehen und für Binärdateien zur Verfügung?
Nenne die Parameterwerte bzw Definitionen.
Schreiben und Lesen:
size_t fwrite(void *buf, size_t size, size_t cnt, FILE *f)
size_t fread(void *buf, size_t size, size_t cnt, FILE *f)
Parameter und Rückgabewert:
- buf: Zeiger auf den Datenpuffer (void * ist ein untypisierter Zeiger, d.h. es darf
ein beliebiger Zeiger übergeben werden)
- size: Größe eines Elements
- cnt: Anzahl der Elemente
- Rückgabewert: Anzahl der verarbeiteten Datensätze
Bsp: LESEN
#define DB_SIZE 50
…
typedef struct s_Customer
{ …
} Customer;
…
FILE file;
Customer myCustomers[DB_SIZE];
/ Daten lesen /
file = fopen(“kundendatei.dat”, “rb”);
if(file == NULL) {
fprintf(stderr, “Fehler beim Oeffnen der Datei!\n”);
exit(EXIT_FAILURE);
}
if(DBGROESSE != fread(myCustomers, sizeof(Customer), DB_SIZE, file)) {
fprintf(stderr, “Warnung: zu wenig Daten in Datei!\n”);
}
fclose(file);
________________________________________________________________________________
Bsp Speichern
…
/ Daten bearbeiten /
…
/ Daten speichern */
file = fopen(“kundendatei.dat”, “wb”);
if(file == NULL)
{
fprintf(stderr, “Fehler beim Oeffnen der Datei!\n”);
exit(EXIT_FAILURE);
}
if(DB_SIZE != fwrite(myCustomers, sizeof(Customer), DB_SIZE, file)) {
fprintf(stderr, “Fehler beim Speichern!\n“);
}
fclose(file);
…
Nenne 3 Weitere Funktionen der stdio.h.
- freopen: Umleiten eines Datei-Streams (meist stdin, stdout oder stderr) in
eine Datei - remove/rename: Löschen bzw. Umbenennen einer Datei
- tmpfile/tmpname: Erzeugen von temporären Dateien
- setvbuf/setbuf: Beeinflussung des Datenpuffers
- ungetc: Zurückstellen eines Zeichens in den Puffer
- fgetpos/fsetpos: Speichern/Setzen der Position im Datei-Stream
- feof: Abfragen, ob Dateiende erreicht
- clearerror/ferror/perror: Funktionen zur Fehlerbehandlung