binärdatei nach zeichenkette durchsuchen
-
Achso ja,
wenn die Datei nicht allzu groß ist, lese sie komplett in den Speicher und lass einen strstr durchlaufen. Dann den ganzen Speicher wieder in die Datei schreiben.
PS: Im vorigen Post habe ich strcmp gemeint, nicht strcat.
-
das prob ist, dass die position in der binärfile varieren kann.
d.h. doch das es passieren kann das meine minizeichenkette durch den buffer zerschnitten wird und dann kein treffer herauskommt.die fssek-funktion hatte ich mir schon mal angesehen. ich komme nur noch nicht ganz mit dem dritten parameter (whence) zurecht.
hat jemand mal bitte ein beispiel für mich?
-
@SeppSchrot: die datei ist ~ 350kb groß.
ich möchte den arbeitsspeicher nicht allzuviel belasten (zumindest nicht die vollen 350kb).
-
stdin schrieb:
@SeppSchrot: die datei ist ~ 350kb groß.
ich möchte den arbeitsspeicher nicht allzuviel belasten (zumindest nicht die vollen 350kb).
*lol* Sehr löblich. Vermutlich cachet das OS die Datei sowieso.
Der 3. Parameter von fseek heißt origin und für ihn sind drei Werte zulässig:
SEEK_SET - Der 2. Parameter gibt die Position vom Anfang der Datei gemessen an.
SEEK_END - Dasselbe vom Ende der Datei aus gesehen.
SEEK_CUR - Der 2. Parameter gibt relativposition zum derzeitigen Filepointer an. Also +1 ist das übernächste Byte, -1 wäre das Byte, das als letztes gelesen wurde.das prob ist, dass die position in der binärfile varieren kann.
d.h. doch das es passieren kann das meine minizeichenkette durch den buffer zerschnitten wird und dann kein treffer herauskommt.Nein, wenn du Zeichenweise voranschreitest, nicht.
Hast du kariertes Papier? Schreib mal einen kurzen Text rein und versuche das mal nachzuvollziehen.
-
stdin schrieb:
das prob ist, dass die position in der binärfile varieren kann.
d.h. doch das es passieren kann das meine minizeichenkette durch den buffer zerschnitten wird und dann kein treffer herauskommtDiese problem lässt sich leicht lösen. du brauchst die puffer nur um die länge der gesuchten zeichenkette überlappen lassen dann findest du die zeichenkette garantiert.
zb länge 5-byte puffergrösse 512 bytes
1. lese von offset 0 - 512 .. durchsuche puffer
2. lese von offset 506 - 1018 ... durchsuche buffer
usw
btw suchen mit strstr ist nicht optimal da strstr bei vorkommen eines 0-bytes teminiert.Kurt
-
irgenwie haut die siche bei mir mit strstr nicht hin:
char * ptr; char line_buffer[63]; while(fgets(line_buffer, sizeof(line_buffer), fd)) { if((ptr = strstr(line_buffer, "socket"))) { printf("POS: %i\n", ptr); } }
der findet "socket" einfach nicht.
das kann doch schon am terminierendem '\0' liegen, oder?
-
Wie gesagt wenn im puffer irgendwo vor der zeichenkette "socket" ein 0-byte steht dann findet strstr deinen string nicht. es wird dir nichts übrigbleiben und zeichenweise zu vergleichen bis du ein 's' findest, dann kannst du von dort aus strstr() verwenden um zu sehen ob es dein gesuchter string ist.
Kurt
-
na dann werd ich wohl das mal probieren...
-
ZuK schrieb:
stdin schrieb:
das prob ist, dass die position in der binärfile varieren kann.
d.h. doch das es passieren kann das meine minizeichenkette durch den buffer zerschnitten wird und dann kein treffer herauskommtDiese problem lässt sich leicht lösen. du brauchst die puffer nur um die länge der gesuchten zeichenkette überlappen lassen dann findest du die zeichenkette garantiert.
zb länge 5-byte puffergrösse 512 bytes
1. lese von offset 0 - 512 .. durchsuche puffer
2. lese von offset 506 - 1018 ... durchsuche buffer
usw
btw suchen mit strstr ist nicht optimal da strstr bei vorkommen eines 0-bytes teminiert.Kurt
@ZuK:
also das mit dem zeichen einlesen dauert mir zu lange!
gibts auf o.g. posting von dir ne andere möglichkeut zeichen in einem buffer zu suchen als mit strstr???
-
schneller wirds nur wenn du einen grösseren buffer verwendest.
Kurt
-
ich sehe gerade du versuchst mit das file mit fgets() zu lesen. dasfunktioniert leider auch nicht. nimm fread().
kurt
-
so ungefähr sollte es funktionieren. ungetestet.
#include <stdio.h> #include <string.h> int main() { FILE * fp = fopen("./m", "r,b" ); char buffer[1024]; char * to_find = "socket"; int slen = strlen(to_find); int found = 0; int idx; char * p; long sp = 0; fseek(fp, 0, SEEK_END); long fsize=ftell(fp); // printf("size=%d\n", fsize); rewind (fp); int szread = fread(buffer,1,1024, fp ); // printf("sp=%d length=%d\n", sp ,szread); while ( sp < fsize && ! found ) { p = buffer; for ( idx = 0; idx < szread; idx++ ) { if ( *p == to_find[0] ) { found = ( strstr( p, to_find ) == p ); if ( found ) break; } p++; } sp += ( 1024 - slen ); fseek( fp, sp, SEEK_SET ); szread = fread(buffer,1,1024, fp ); // printf("sp=%d length=%d\n", sp ,szread); } }
Kurt
-
danke kurt,
funzt zwar nicht, aber ich hab wenigstens ein beispiel.
irgendwie läuft fread auch nicht in der schleife ???
edit: <sorry> funzt wunderbar
ich habe nur den ersten aufruf von fread in eine while-schleife gepackt und es klappt prima !
-
wenn du die printf aktivierst solltest du sehen dass das file zumindest komplett gelesen wird. Also soweit sollte es funktionieren. Bin mir nicht ganz sicher mit dem strstr.
Kurt
-
stdin schrieb:
ich habe nur den ersten aufruf von fread in eine while-schleife gepackt und es klappt prima !
Dann musst du den zweiten aber weglassen.
K
-
klappt 100%
ein problem hab ich noch:
FILE * fd = fopen(file, "wb" ); // Anfang des zu überschreibenden Bytes fseek( fd, end_offset, SEEK_SET ); printf("%i\n", ftell(fd)); putc('e', fd); fclose(fd);
wenn ich mit putc oder mit fputc ein zeichen an die offset-position schreiben möchte macht er dies zwar, jedoch wird der anfang bis zu dieser pos. mit 0x00 aufgefüllt und der rest abgeschnitten.
was mach ich flasch???
-
okay, hat sich erledigt, wenn man den access_mode nicht entsprechend setzt kann es ja auch nicht klappen <also manchmal>