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)