Fread und Malloc
! Dateien mit fread und malloc in den Speicher lesen Hier mal eine kleine Demonstration, wie man mit C Textdateien einlesen kann. Wie so oft, gibt's auch hier wieder zahllose Möglichkeiten:
- Unterscheidung nach Standard
- ANSI-C Funktionen fopen, fread, fwrite, fclose (sehr portabel)
- POSIX Funktionen open, read, write, close (POSIX halt, sprich nur Unix-ähnliche Systeme, dafür schneller)
- Unterscheidung nach Herangehensweise
- Dateien Zeile für Zeile lesen und weiterverarbeiten
- Dateien Block für Block (z.B. jeweils 4096 Zeichen) lesen und dann komplett im Arbeitsspeicher halten/bearbeiten (das ist übrigens für größere Dateien nicht zu empfehlen) :-)
| fopen(NAME,TYP) | Datei NAME öffnen, TYP r zum Lesen, w zum Schreiben |
| fread(BUF,BLOCKSIZE,COUNT,HANDLE) | lese COUNT Blöcke der Größe BLOCKSIZE aus dem Dateihandle HANDLE und speichere in BUF. Rückgabe: Anzahl der gelesenen Blöcke |
| fwrite(BUF,BLOCKSIZE,COUNT,HANDLE) | schreibe COUNT Blöcke der Größe BLOCKSIZE in das Dateihandle HANDLE und nehme die Daten aus dem Speicherbereich von BUF - Rückgabe: Anzahl der geschriebenen Blöcke |
| fclose(HANDLE) | Schließe das Dateihandle HANDLE |
- Infos bezüglich realloc und free siehe ((CodingTutorialC-PrimGmp|hier))
- wenn fopen die Datei nicht öffnen kann (weil sie zum Beispiel schlicht nicht existiert oder die Permissions nicht reichen), wird ein NULL-Pointer zurück gegeben. Dies sollte immer mit if oder ähnlichem kontrolliert werden.
/* Copyleft(C) 2005 Stefan Siegl <ssiegl@gmx.de>
* no right reserved.
*
* example demonstrating use of fopen/fread in
* conjunction with malloc/realloc
*/
#include <stdio.h>
#include <malloc.h>
static char *read_my_file(const char *filename);
int
main(void)
{
char *buffer = read_my_file("christian.txt");
if(! buffer) {
fprintf(stderr, "unable to read file, getting outta here\n");
return 1;
}
printf("this is kinda expensive cat ...\n");
printf("%s", buffer);
/* get rid of allocated memory,
* you mustn't use 'buffer' after that
*/
free(buffer);
return 0;
}
static char *
read_my_file(const char *filename)
{
char *buf = NULL;
size_t alloc = 0;
size_t len = 0;
FILE *handle = fopen(filename, "r");
if(! handle) return NULL; /* unable to open file */
for(;;) {
size_t read_bytes;
if(len >= alloc) {
/* we need more memory, allocate some ... */
buf = realloc(buf, alloc = (alloc == 0 ? 4096 : alloc << 1));
if(! buf) return NULL; /* unable to allocate memory */
}
/* call fread to read the next characters from our file handle,
* named 'handle'. We request it to store to our buffer with
* offset 'len' (the number of bytes we've already read).
* We must not store more than 'alloc - len' bytes as we'd
* write over the end of our allocated buffer then. */
if((read_bytes = fread(buf + len, 1, alloc - len, handle)) <= 0)
break; /* read until end of file (or error) */
len += read_bytes;
}
fclose(handle); /* close file */
buf = realloc(buf, len + 1); /* shrink buffer to the
* necessary size */
if(! buf) return NULL;
buf[len ++] = 0; /* terminate string */
return buf;
}
- obenstehenden Code bitte in fread.c abspeichern
- gcc -o fread fread.c -Wall -W -ggdb -O ausführen
- ./fread ausführen
- eine Datei christian.txt anlegen
- nochmal ausführen ^^
- staunen :-)
- Fragen hier ergänzen (-> FAQ)