fread und fwrite anstatt fprintf und fscanf


Dieses Tutorial soll erläutern, wie das Lesen aus Datein beschleunigt und vereinfacht werden kann. Angenommen ihr habt vollgendenen Codeausschnitt um mehrere Integer aus einer Datei in ein Array einzulesen:
FILE *datei;
int zahlen[25];

if ((datei = fopen("test.txt", "r")) == NULL)
    return 0;

for (int i = 0; i < 25; i++)
{
    fscanf(datei, "%d", zahlen[i]);
}

fclose(datei);
Der Nachteil dieser Methode ist, dass jeder Integer einzeln eingelesen werden muss und eine For-Schleife benötigt wird. Schneller wäre es, wenn alle Integer auf einmal ausgelesen werden. In C/C++ gibt es dazu die Funktionen fread und fwrite, mit ihnen kann ein ganzer Block (Record) aus einer Binärdatei ausgelesen werden. Da es sich um eine Binärdatei handelt, muss die Datei vorher auch binär beschrieben werden (z.B. mit fwrite, ...).
Die Definition:
size_t fread( void *buffer, size_t size, size_t count, FILE *stream );
size_t fwrite( const void *buffer, size_t size, size_t count, FILE *stream );
als Header muss nur <stdio.h> eingebunden werden. Und nun zum Einlesen des Arrays mit fread und fwrite:
FILE *datei;
int zahlen[25];

if ((datei = fopen("test.txt", "rb")) == NULL)
    return 0;

fread(zahlen, sizeof(int), 25, datei);

fclose(datei);
Der Vorteil ist liegt auf der Hand, die For-Schleife und damit auch ihre Variable entfällt und die Integer werden mit einem Zug eingelesen. Die Datei muss mit "rb" geöffnet werden, um fopen zu signalisieren, dass wir im binär-modus lesen wollen. Nun zu fread: das erste Argument ist ein Pointer auf den zu schreibenden Bereich (in unserem Fall das Integer-Array), das 2. Argument gibt die Größe des zu lesenden Elements an, nun folgt die Anzahl der zu lesenden Elemente und zuletzt die Datei aus der gelesen werden soll.

Es gibt aber noch weitere Vorteile, fread und fwrite können sehr gut eingesetzt werden um Strukturen aus Dateien zu lesen. Wenn ihr folgende Struktur habt, z.B. in einem Adressbuch.
typedef struct EINTRAG_TYP
{
    short alter;
    int geburtsjahr;
    char name[20];
} EINTRAG;
Um so eine Struktur in eine Datei zu schreiben benutzt ihr einfach fwrite, ich gehe davon aus, dass ihr bereits eine Variable mit Namen eintrag vom Typ EINTRAG deklariert habt.
FILE *datei;

if ((datei = fopen("test.txt", "wb")) == NULL)
    return 0;

fwrite(&eintrag, sizeof(EINTRAG), 1, datei);

fclose(datei);
Und schon hab ihr den ganzen Datensatz in die Datei geschrieben, natürlich muss die Datei mit "wb" geöffnet werden. Nun noch ein letztes triviales Beispiel um mehrere Datensätze wieder zu lesen.
FILE *datei;
EINTRAG eintrag[10];

if ((datei = fopen("test.txt", "rb")) == NULL)
    return 0;

fread(eintrag, sizeof(EINTRAG), 10, datei);

fclose(datei);
Ist doch ganz einfach oder? Was ihr beachten müsst, ist dass wenn ihr nur den Namen von einem Array verwendet (z.B. eintrag), könnt ihr den Adress Operator (&) weglassen!


Ein Tutorial von Lion Vollnhals (28.12.2001), lion.vollnhals@web.de