[FILE*] Wie auf _ptr zugreifen?
-
Und wenn man den Puffer nicht jeweils um eine bestimmte Anzahl Bytes, sondern um einen bestimmten Faktor vergrößert (z.B. verdoppelt), ist der Aufwand selbst dann noch linear, wenn bei jedem realloc der Puffer kopiert wird.
-
Pyro Phoenix schrieb:
Klingt nach zuviel overhead.
Würde das eigentlich gerne möglichst effizient regeln.
Undzwar sollen die Zeilen direkt als strings in eine LinkedList geladen werden.struct Line { unsigned char *sz_string; struct Line *next; struct Line *prev; };
Du kannst du dich nach einer getline-ähnliche Implementierung http://www.c-plusplus.net/forum/viewtopic-var-p-is-1686949.html#1686949 keine effiziente Implementierung (siehe namespaces Beitrag) aber zumindet ein Anhaltspunkt für dich.
Auf fertige Dinge wollte nich noch nicht zurückgreifen.
man sollte nicht das Rad neu erfinden
-
Ich hab das jetzt so geregelt:
#include <stdio.h> #include <string.h> struct Line { unsigned char *sz_string; struct Line *next; struct Line *prev; }; int main (int argv, char *argc[], char *envp[]) { FILE *fp_indata; unsigned char *sz_buffer; Line *root, *actv; fpos_t actfile = 0; fpos_t firstchar = 0; fpos_t lastchar = 0; root = new struct Line; root->prev = NULL; root->next = NULL; root->sz_string = NULL; sz_buffer = new unsigned char[2]; sz_buffer[1] = NULL; if ( ( fp_indata = fopen("C:\\testdaten.txt", "rb") ) == NULL ) { printf("File not found.\n"); } else { actv = root; while ( !feof(fp_indata) ) { fsetpos (fp_indata, &actfile); firstchar = actfile; while ( *sz_buffer >= 0x20 ) { fread ( sz_buffer, sizeof(unsigned char), 1, fp_indata); actfile++; }; lastchar = actfile -1; while ( *sz_buffer <= 0x0F ) { fread ( sz_buffer, sizeof(unsigned char), 1, fp_indata); actfile++; }; fsetpos (fp_indata, &firstchar); actv->sz_string = new unsigned char [(long)(lastchar-firstchar)]; fread (actv->sz_string, sizeof(unsigned char), (long)(lastchar-firstchar), fp_indata); actv->sz_string[(long)(lastchar-firstchar)] = 0x00; if ( !feof(fp_indata) ) { actv->next = new struct Line; actv->next->prev = actv; actv = actv->next; actv->next = NULL; actv->sz_string = NULL; } actfile--; } } fclose (fp_indata); return 0; }
Aber nach dem 2. Durchlauf der Schleife habe ich plötzlich Probleme mit dem FILE Pointer. Das äussert sich folgendermaßen:
Durchlauf 1:
http://img18.imageshack.us/img18/8938/capture08042009005024.jpg
Durchlauf 2:
http://img19.imageshack.us/img19/5940/capture08042009005032.jpg
Durchlauf 3:
http://img16.imageshack.us/img16/1306/capture08042009005047.jpg
testdaten.txt
Hallo Welt ! Dies ist eine Testdatei ! EOF
Woran liegt das, das der plötzlich verrückt spielt ?
Mag der das setpos nicht oder wie ?
-
Pyro Phoenix schrieb:
#include <stdio.h> #include <string.h> ... root = new struct Line; ... actv->next = new struct Line; ... }
igit.... häßliche Mischung von C und C++. Entweder C oder C++ aber nicht beide!
-
Das behebt das Problem leider auch nicht.
-
Das fsetpos in Zeile 40 muss fgetpos sein.
Ansonsten schließe ich mich der Meinung von supertux an.
Und das Rumrechnen mit fpos_t ist nicht portabel, das könnte nämlich auch eine Struktur sein. Du solltest die Stringlänge lieber in einem Integer (oder besser size_t) zählen.
-
zu dem Code fällt mir nur eins: wieso einfacher, wenn es schwieriger geht
-
Pyro Phoenix schrieb:
Klingt nach zuviel overhead.
Würde das eigentlich gerne möglichst effizient regeln.Der Overhead dabei ist logarithmisch, d.h. absolut in Ordnun aus Informatiksicht. Und wenn du den selben Buffer für jede Zeile benutzt, dann kannst du den Overhead noch durch die Anzahl der Zeilen teilen und kommst dann auf einen sehr kleinen Overhead auf die gesamte Datei gerechnet.
Alternativ benutzt du eine Liste welche deine Buffer enthält und jedes mal wenn der Buffer am Ende voll ist erzeugst du einen neuen mit N Bytes Platz und hängst ihn hinten an. So wäre der Speicherverbrauch geringer bei einer Datei mit 2^n+m Zeichen, wobei m deutlich kleiner als 2^n sein sollte (z.B. m=1 und bei großem n auch noch m=1000).
-
Nach sovielen Tipps hab ich nun echt keine Ahnung mehr, wie ich das regeln soll. Der eine meckert über meinen Programmierstil - was ich durchaus nachvollziehen kann - und der nächste gibt einem Tipps, mit denen ein Laie nix anzufangen weiß.
namespace invader schrieb:
Das fsetpos in Zeile 40 muss fgetpos sein.
Ne eben nicht, weil sonst wieder ein Newline Zeichen eingelesen wird - und das ganze dann in einer Endlosschleife endet.
-
namespace invader schrieb:
Und das Rumrechnen mit fpos_t ist nicht portabel, das könnte nämlich auch eine Struktur sein. Du solltest die Stringlänge lieber in einem Integer (oder besser size_t) zählen.
Dann hab ich aber Probleme mit setpos, da das ein fpos_t als Datentyp erwartet.