Zeilenweise aus einer Datei lesen geht nich
-
Hallo, ich habe ein Problem mit dem "zeilenweisen einlesen" aus einer Datei, welches ich mir in etwas so vorgestellt habe:
/* returns a valid FILE* or NULL //*/ FILE* get_read_file_pointer(char filename[FILENAME_MAX]) { #ifdef DEBUG printf("fo::get_read_file_pointer(\'%s\')\n", filename); #endif FILE* fp = NULL; if(filename == NULL) return NULL; if((fp = fopen(filename, "r")) == NULL){ perror("Reading \'%s\' failed! "); return NULL; } return fp; } /* reads the whole file linewise into a char* with a buffer of the given size //*/ // FIXME: Segmentations fault - core dumped!? int read_linewise(FILE* fp, char* content) { #ifdef DEBUG printf("read_linewise(fp, \'%s\')\n", content); #endif #ifdef __unix__ int c; size_t *tp = malloc(0); char **gptr = (char**) malloc(sizeof(char*)); *gptr = NULL; while( (c=getline(gptr, tp, fp)) > 0){ strcat( content, *gptr); } return 0; #endif const unsigned int BUFFERSIZE = BUFSIZ; // *pBUF; int len = 0; char buffer[BUFFERSIZE]; while(fgets( buffer, BUFFERSIZE, fp) != NULL){ len += strlen(buffer) + 1; if(len < BUFFERSIZE) strcat(content, buffer); else return -1; } return 0; };
In einer Funktion, bspw. main() will ich das dann in etwa so aufrufen:
// ... char *content = malloc(255*sizeof(char)); content = ""; // ... printf("Get read file pointer to %s\n", file2); fp = get_read_file_pointer(file2); printf("Reading from a file linewise: %i\n", read_linewise(fp, content)); printf("%s\n", content); // ...
Ich kompiliere das ganze per Cygwin auf Windows und bekomme folgende Meldung:
Get read file pointer to file2.txt
7 [main] fo 1964 _cygtls::handle_exceptions: Error while dumping state (probably corrupted stack)
Segmentation fault (core dumped)Was mache ich falsch?
-
Fabeltier schrieb:
char *content = malloc(255*sizeof(char)); content = "";
Das ist schonmal falsch - du legst erst genug Platz für 255 Zeichen an (soweit OK) und biegst deinen Zeiger anschließend um auf ein leeres String-Literal (das ist erstens zu klein für die Daten und zweitens read-only*). Wenn du den gerade beschafften String mit "" füllen willst, nimm lieber
strcpy(content,"");
odercontent[0]='\0';
.Außerdem ist nicht ganz klar, was deine Funktion 'read_linewise'() eigentlich macht - du liest solange weiter, bis die Gesamtdaten größer als BUFFERSIZE sind (und sobald die Datei größer als das ist, gibt die Funktion -1 zurück, nachdem sie die letzte gelesene Zeile weggeworfen hat).
* und drittens hast du ein Speicherleck, weil niemand mehr die Adresse des angeforderten Speichers kennt.
-
Hallo,
Zur Initialisierung - was ich eigentlich will ist einen String anlegen, also einen Zeiger auf eine mit '\0' terminierte Zeichenkette. Diese sollte maximal 255 Zeichen "fassen" koennen (waere wohl 256 besser wegen '\0', aber ok). Diese will ich quasi leer machen, also mit "" initialisieren.Mir ist hier selber die Rolle des Puffers nicht ganz klar (habe den Code u.a. aus einem Buch und spiele damit rum). Ich versuche irgendwie einen Puffer anzulegen mit Laenge BUFFERSIZE, dieser sollte fuer eine Zeile angelegt werden. In diesen Puffer soll dann eingelesen werden und nach je einer Zeile der gesamte Puffer an *content angehaengt werden. Uebersteigt die Laenge einer Zeile die Groesse BUFFERSIZE, also die max zulaessige Zeilenlaenge, dann soll nicht mehr eingelesen werden, weil irgendetwas mit dem File nicht stimmt - daher sollte -1 zurueckgegeben werden. Ich sehe mittlerweile selber, dass ich auch die Groesse von *content mituebergeben muesste, damit nicht ueber dessen Laenge hinausgeschrieben wird, oder besser die Moeglichkeit anbieten, content entsprechend zu erweitern, wenn content zu klein ist.
1. Ist also:
strcpy(content, "");
fuer die Initialisierung mit 'leer' ueberhaupt ausreichend, oder muss muss ich nun 254 mal (bzw 255 mal) in einer "for"-Schleife " " setzen?
2. Wie haenge ich den eingelesenen Puffer einer Zeile am besten an *content an, ist strcat() fuer diese Aufgabe ausreichend bzw. die beste Wahl?
3. Gibt es eine Konstante in C die etwa eine max Zeilenlaenge auf dem jew System angibt? Oder gibt es da Konventionen bezueglich dieser Laenge?
-
1. Ja, strcpy() ist ausreichend.
2. Wenn du davon ausgehst, daß der Puffer leer ist, kannst du ihn auch mit strcpy() füllen.
3. Nein, es gibt keine maximale Zeilenlänge - eine Zeile wird so lang, bis ein '\n' kommt.
-
Also ich habe nun weiter dran rumgefriemelt und gehe nun folgendermassen vor - was kann ich daran verbessern, bzw welche Fehler mache ich dabei? Soweit laeuft die Funktion, wie erwartet, sie liest mir zeilenweise alles in den Zeiger *content ein.
int read_linewise(FILE* fp, char* content) { strcpy(content, ""); #ifdef __unix__ int c; size_t *tp = malloc(0); char **gptr = (char**) malloc(sizeof(char*)); *gptr = NULL; while( (c=getline(gptr, tp, fp)) > 0){ strcat( content, *gptr); } return 0; #endif int isEOF = 0; int len = 0; char bufLine[LEN_LINE]; strcpy(bufLine, ""); while( (fgets( bufLine, LEN_LINE, fp) != NULL) && (*bufLine != EOF)){ *bufLine = '\0'; len += strlen(bufLine); strcat(content, bufLine); if(len >= LEN_LINE) return -1; } return 0; };