wie gefällt euch diese funktion zum auslesen von textdateien ?
-
so die funktion dient dazu, grafik API´s wie opengl und SDL die initialisierung zb. die auflösung einstellen zu können, bevor das programm überhaupt gestartet wird.
#include <stdio.h> #include <stdlib.h> #include <string.h> struct data{ short width; short height; short bpp; char name[100][100]; //name der befehle }a; int dataOption() { FILE *init; int anzahl; //anzahl der befehle init=fopen("init.txt","r"); if(!init) { printf("datei konnte nicht gefunden werden\n"); return -1; } for(int i=0; !feof(init); i++) { fscanf(init,"%s",a.name[i]); } for(i=0, anzahl=strlen(a.name[i]); anzahl; i++, anzahl--) { if(strcmp(a.name[i],"width=")==0) a.width=atoi(a.name[i+1]); if(strcmp(a.name[i],"height=")==0) a.height=atoi(a.name[i+1]); if(strcmp(a.name[i],"bpp=")==0) a.bpp=atoi(a.name[i+1]); } printf("%dx%d, %d\n",a.width,a.height,a.bpp); fclose(init); return 0; }
vorallem aber dachte ich mir, das ich das in das forum schicke, damit sich andere kluge kpfe damit mal beschäftigen und ihren "senf" dazu geben können
ich meine ich bin auch nur ein anfänger und lerne gern dazu ...
na dann haltet euch bitte nciht zurück
-
ich würde bemängeln, dass die funktion nicht fehlertolerant ist. wenn man bei fscanf nicht genau hinschaut, bekommt man leicht einen pufferüberlauf. es gibt auch keine garantie, dass sich höchtens 100 einträge in der datei befinden.
das erste problem kann man leicht lösen:
fscanf(init,"%99s",a.name[i]);
damit werden höchtens 99 zeichen gelesen, das 100. zeichen im array dient zur not der terminierung. das zweite problem ist genauso einfach.
-
jupp stimtm, nur wie würde es denn aussehen, wenn ich das zweidimensionale array, das sich in der structur data befindet, dynamisch machen würde ?
malloc und realloc kann ich ja eindimensionale arrays aus einem pointer zumbeispiel erstellen, aber zweidimensionalen ... (sind ja quasi doppelpointer nicht wahr ?struct data{ short width; short height; short bpp; char name[100][100]; }a;
währe es nicht äquivalent zueinander, wenn ich schreiben würde
struct data{ short width; short height; short bpp; char **name; }a;
oder
struct data{ short width; short height; short bpp; char *name[100]; }a;
nur leider würde das in meinem programm einen speicherzugriffs fehler provozieren ...
hat da jemand eine idee ?
-
doomcalyptica schrieb:
jupp stimtm, nur wie würde es denn aussehen, wenn ich das zweidimensionale array, das sich in der structur data befindet, dynamisch machen würde ?
malloc und realloc kann ich ja eindimensionale arrays aus einem pointer zumbeispiel erstellen, aber zweidimensionalen ... (sind ja quasi doppelpointer nicht wahr ?struct data{ short width; short height; short bpp; char name[100][100]; }a;
währe es nicht äquivalent zueinander, wenn ich schreiben würde
struct data{ short width; short height; short bpp; char **name; }a;
oder
struct data{ short width; short height; short bpp; char *name[100]; }a;
nur leider würde das in meinem programm einen speicherzugriffs fehler provozieren ...
hat da jemand eine idee ?nein, char a[100][100], char **a und char *a[100] sind 3 unterschiedliche Sachen, du kannst mit ihnen praktisch das gleiche tun und gliech arbeiten aber äquivalent sind sie nicht.
-
zumal, was ist wenn ich zum beispiel die textdatei auskomentieren würde ... pro token (zeichen/strings zwischen leerzeichen) würden ein bereich des feldes a.name wegnehmen ... vermutlich bleibt nicht viel übrig...
gibt es nun eine ähnliches malloc/realloc nur für 2zwei dimensionale arrays ?
-
du könntest eine flexiblere struktur verwenden. z.b. eine verkettete liste.
-
Warum denn das ganze so kompliziert??
Geh hald die Datei Zeile für Zeile durch und überprüfe gleich bei der aktuellen Zeile, was drin steht.
Also ungefähr so:
//PSEUDO-Code char zeile[128]; char * parameter; while(zeile_einlesen(zeile)) { code = pruefe_zeile(zeile, ¶meter); switch(code) { case width: setze_width(parameter); break; case height: setze_height(parameter); break; case bpp: setze_bpp(parameter); break; default: //wenn was ungültiges drin steht schreibe_logdatei(zeile); break; } }
Die Funktion, die hinter pruefe_zeile() steht, sieht so aus:
#define ANZ_BEFEHLE 3 //oder //const unsigned ANZ_BEFEHLE = 3; int pruefe_zeile(const char * zeile, char ** parameter) { char befehle[ANZ_BEFEHLE][] = {"width=", "height=", "bpp="}; int i, anz; for(i = 0; i < ANZ_BEFEHLE; ++i) { anz = strlen(befehle[i]); if(!strncmp(befehle[i], zeile, anz)) { *parameter = zeile + anz; return(i); } } return(-1); }