[C] zoeken naar string in file deel 2

Pagina: 1
Acties:
  • 103 views sinds 30-01-2008
  • Reageer

  • SWfreak
  • Registratie: Juni 2001
  • Niet online
Ben ik weer :) In deel 1 zaten een paar goede oplossingen, alleen met mijn :r C-compiler werken memmoves, -copys niet goed. Dus moet het met string-operaties. Eenvoudig dacht ik, dus ik probeerde
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
int fstrstr(FILE *fp, const char* searchString, int bufsize)
{
char *readString;
int searchLength, restLength;
char *pos = NULL;
int posDiff, found = 0;

searchLength = strlen(searchString);
restLength = bufsize - searchLength;
if(searchLength > bufsize)
return 0;

readString = (char *D malloc(bufsize + 1);
if(readString == NULL)
return 0;

printf("%i %i\n", searchLength, restLength);

while(!feof(fp))
{
strncpy(readString, readString + restLength - 1, searchLength);
if(fgets(readString + searchLength, restLength, fp) == NULL)
//if(fread(readString + searchLength, restLength, 1, fp) <= 0)
break;

pos = strstr(readString, searchString);
if(pos != NULL)
{
printf("FOUND\n");
posDiff = readString - pos;
fseek(fp, -posDiff, SEEK_CUR);
found = 1;
break;
}

}

free(readString);

return found;
}

Alleen dit werkt niet goed. Iemand een idee wat wel werkt?

  • Infinitive
  • Registratie: Maart 2001
  • Laatst online: 14-09 09:56
Ben ik weer :)alleen met mijn :r C-compiler werken memmoves, -copys niet goed.
:?
Overlappen je geheugengebieden elkaar dan?
Want memcpy is toch in weze niet veel meer dan:
code:
1
2
for(i=0; i < size; i++)
    *ptr1++ = *ptr2++;

maar dan in assembler.
Dus als dat het al niet doet...

putStr $ map (x -> chr $ round $ 21/2 * x^3 - 92 * x^2 + 503/2 * x - 105) [1..4]


  • SWfreak
  • Registratie: Juni 2001
  • Niet online
Op maandag 29 oktober 2001 21:31 schreef Infinitive het volgende:

[..]

:?
Overlappen je geheugengebieden elkaar dan?
Want memcpy is toch in weze niet veel meer dan:
code:
1
2
for(i=0; i < size; i++)
    *ptr1++ = *ptr2++;

maar dan in assembler.
Dus als dat het al niet doet...
Nee daar ligt het denk ik niet aan. Ik ben nog wat aan het rommelen en zelfs in een file van 112 bytes doet hij het niet goed. Ik denk dat het aan het inlezen ligt. Als ik een fread of fgets doe dan leest ie niet genoeg karakters. fread(buffer, 200, 1, fp) levert maar 5 karakters gelezen op. :??? Ik snap dat even niet.

  • SWfreak
  • Registratie: Juni 2001
  • Niet online
Snap het nu. Als ik strstr op een binary-string probeer te doen die NULL's bevat, dan werkt dat natuurlijk niet :) eigen strstr schrijven wordt dat. En ik had de fread-params omgedraaid. |:(

  • marcusk
  • Registratie: Februari 2001
  • Laatst online: 26-09-2023
Op dinsdag 23 oktober 2001 09:22 schreef farlane het volgende:
En wat als er \0 karakters in staan?
Volgens mij gaat dit niet (helemaal) werken zo.
Had farlane dus toch gelijk :)

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 16-09 23:59
Ha, dus toch! ;)

ps, er is ook een functie die een binary compare van een geheugenblok doet. Iets van memcmp(...) oid

[edit]

Eventjes netjes een urrel opgezocht:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/HTML/_crt_memcmp.asp

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • SWfreak
  • Registratie: Juni 2001
  • Niet online
Op maandag 29 oktober 2001 22:43 schreef farlane het volgende:
Ha, dus toch! ;)

ps, er is ook een functie die een binary compare van een geheugenblok doet. Iets van memcmp(...) oid
Helemaal gelijk :). Ik heb even naar memcmp gekeken, maar het niet geprobeerd, omdat die ook praat over strings-vergelijken. Heb eigen functie geschreven en alles werkt perfect!! Bedankt voor de hulp en als desert nog even de werkende code:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
int fstrstr(FILE *fp, const char* searchString, int bufsize)
{
    char *readString;
    int searchLength, restLength;
    int pos, found = 0, bytesRead;

    searchLength = strlen(searchString);
    restLength = bufsize - searchLength - 1;
    if(searchLength > bufsize)
        return 0;

    readString = (char *) malloc(bufsize + 1);
    if(readString == NULL)
        return 0;

    while(!feof(fp))
    {
        bytesRead = fread(readString, 1, restLength, fp);

        pos = strstrb(readString, searchString, bytesRead, searchLength);

        if(pos != -1)
        {
            fseek(fp, -(bytesRead - pos), SEEK_CUR);
            found = 1;
            break;
        }

    }

    free(readString);

    return found;
}

int strstrb(const char *haystack, const char *needle, size_t hayLength, size_t needleLength)
{
    int i, j;

    for(i = 0; i < hayLength; i++)
    {
        for(j = 0; j < needleLength; j++)
        {
            if(haystack[i + j] != needle[j])
                break;
        }
        if(j == needleLength)
            return i;
    }

    return -1;
}

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 16-09 23:59
int memcmp( const void *buf1, const void *buf2, size_t count );
en verderop....
buf1 First buffer

buf2 Second buffer

count Number of characters
Waar je uit zou kunnen destilleren dat er [count] karakters (==bytes en dus !=string ) vergeleken worden, itt strcmp die de lengte van de string neemt.

Je mag er van uit gaan dat alles wat je bedenkt op het gebied van dit soort problemen, al op een betere manier is opgelost. :)

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Verwijderd

Op maandag 29 oktober 2001 22:58 schreef farlane het volgende:
Waar je uit zou kunnen destilleren dat er [count] karakters (==bytes en dus !=string ) vergeleken worden, itt strcmp die de lengte van de string neemt.

Je mag er van uit gaan dat alles wat je bedenkt op het gebied van dit soort problemen, al op een betere manier is opgelost. :)
Mja, maar memcmp() is toch geen complete oplossing? Je kunt er alleen even lange binary strings mee vergelijken, en je zult dus een loop moeten bouwen die de langere string byte voor byte afloopt en tegen de kortere memcmp()t. Dan zit je dus weer met een O(n*m) oplossing.

Ik ben in die vorige topic begonnen met het lezen van binary strings omdat je zo langere strings in eens kunt vergelijken, wat gunstig is voor de prestatie van een Boyer-Moore search. Het BM-algoritme zorgt er zelf voor dat er aan het begin van een nieuwe string verder wordt vergeleken als er een karakter voorkomt dat niet in de zoekstring staat, zoals bv. een NULL.

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 16-09 23:59
Daar heb je natuurlijk gelijk in, maar ik doelde hier eigenlijk alleen op het feit dat er een binary compare functie gezocht werd.

En die is er al, en waarschijnlijk een goedkopere implementatie dan een for-loop. (Alhoewel dat natuurlijk geen beproefd argument is.)

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • SWfreak
  • Registratie: Juni 2001
  • Niet online
Ja ik zou het nog naar BM kunnen omschrijven met string-operaties, maar ik ben eigenlijk al blij dat het werkt en het gaat best wel snel (op een file van ruim 2 mb binnen 4 seconden alle 1000 hits gevonden). Aangezien ik het later nog naar PHP wil omzetten, zal ik er denk ik geen memcmp erin zetten, ookal gaat dat ongetwijfeld sneller.

  • Remenic
  • Registratie: Juni 2001
  • Laatst online: 09-08 20:06
code:
1
readString = (char *D malloc(bufsize + 1);

hee dit klopt niet?? Mist een haakje volgens mij ;)

edit:
oh wacht es, de D hoort een ) te zijn... :D
Pagina: 1