fgets() und die Zeilenlänge??
-
Hallo Coders,
mal ne frage:
Wenn ich ja die Funktion fgets() benutze um eine Datei zu lesen, muss ich ja die Größe des Buffers angeben. Was ist nun aber, wenn ich die länge der Zeile nicht weis, und ich sie dynamisch allokieren möchte? Gibt es da eine möglichst performante und schnelle Lösung???
Sicher könnte ich nun daher gehen und mir die Zeile und anschließend das Zeilenende suchen oder gleich einen String mit der Größe der Datei allokieren - aber es gibt doch bestimmt noch eine andere Lösung als diese äusserst unperformanten?!
Bin schonmal sehr auf Eure Antworten gespannt
!
Grüsse
~code_pilot
-
einfach lesen und neu lesen, bis irgendwann das ende der zeile erreicht ist.
immer in schön netten brocken wie zB 256 oder 1024 bytes.
du kannst nicht wissen wo die zeile aus ist ohne sie vorher gelesen zu haben...
-
ist der puffer kürzer als die zeile, dann hängt fgets() zwar immer noch eine '\0' aber kein '\n' an das ende des puffers an. daran kannst du erkennen, ob fgets() tatsächlich die ganze zeile eingelesen hat oder nur einen teil. die sache wird noch dadurch ein wenig erschwert, daß die letzte zeile der textdatei nicht mit '\n' abgeschlossen sein muß. da muß man dann noch feof() heranziehen.
hier mal eine implementation, die den speicher bei bedarf vergrößert:
#include <stdlib.h> #include <stdio.h> #include <string.h> char *freadline (FILE *fp) { static char *line = NULL; static size_t line_size = 1024; char *cp; size_t rest_size; if(!line) line=malloc(line_size); cp = line; rest_size = line_size; while(fgets(cp,rest_size,fp), !ferror(fp) && strlen(cp)>0 && cp[strlen(cp)-2]!='\n' && !feof(fp)) { line_size+=1024; realloc(line,line_size); rest_size = line_size-strlen(line); cp = line+strlen(line); } return (ferror(fp) || !line[0] ? NULL : line); }
-
Hallo,
Danke für eure Antworten.
Die Problematik, die ich habe ist aber auch noch die: Ich will Zeilen aus unterschiedlichen Positionen aus einer Datei lesen. D.h. ich sage: Ermittle mir Zeile 5432 aus der Datei XYZ.TXT. Das Problem dahinter ist nun, dass ich erst bis zur Zeile 5432 lesen muss - und das kostet viel Zeit! Kann man das ermitteln der Zeilen denn irgendwie beschleunigen?Denn folgender, jetziger Code, ist meiner Meinung nach uneffektiv und viel zu langsam:
//Nur als Beispiel! long linetoread = 5432; char ch = (char)NULL; char line[1024 + 1]; FILE* stream = (FILE*)NULL; stream = fopen( "C:\\xyz.txt", "rt" ); if( stream == (FILE*)NULL) return -1; if( linetoread > 1 ) { do { if( (ch = fgetc( stream )) == EOF ) break; if( ch == '\n' ) linetoread--; } while( linetoread > 1 ); } if(fgets( line, 1024, stream ) != (char*)NULL) printf("Die gelesene Zeile lautet: %s\n", line ); fclose( stream );
Grüße,
~code_pilot
-
Nein, schneller geht es leider nicht (besonders da Zeilen (a) unterschiedlich lang sein können und (b) physisch gar nicht existieren). Wenn du immer auf der selben Datei arbeitest, könntest du sie am Anfang komplett in ein Array einlesen und dir dann die Zugriffe beschleunigen.
-
Hallo CStoll,
hmm joa okay danke erstmal. Leider kann ich das nicht mappen, da auch aus unterschiedlichen Dateien gelesen wird.
Naja egal
Danke euch!
~cp :xmas2: