Wie oft tritt eine bestimmte Zeichenfolge in einer ASCII datei auf?



  • Hallo Freunde!
    ich versuche die Häufigkeit einer bestimmten Zeichenfolge in einer Datei zu ermitteln. Hierfür habe ich folgenden Code geschrieben:

    int check(){
    int i,j,k,l,m,n;
    
    int l1,l2,l3,l4;
      fpos_t position;
    
      i=j=k=l=m=n=0;
      pFile=fopen ("stuetze.csv","r");
      if (pFile==NULL) perror ("Error opening file");
      else
      do {   
       l1= fgetc (pFile);
       fgetpos (pFile, &position);
       l2= fgetc (pFile);
       l3= fgetc (pFile);
       l4= fgetc (pFile);
       if ((l1 == (int)'y') && (l2 == (int)' ') && (l3 == (int)'1') && (l4 == (int)'"')) k++;
       fsetpos (pFile, &position);
       n++;
       } while (l4!= EOF);
      printf ("Datei beinhaltet %i mal die Zeichenfolge xxx .\n",k);
      return (0);
      }
    

    Die Funktion läuft fehlerfrei durch allerdings funktionniert sie nicht.
    k=0 und l1=l2=l3=l4=-1
    zuerst hatte ich das selbe mit einem Char array versucht allerdings kam es zu dem gleichen Ergebnis. Außerdem liest die Funktion fgetc ja ein char ein und gibt ein int zurück.
    die Konvertierung von char zu int sollte nicht das Problem sein..
    Vielleicht könnt ihr mir ja sagen wo es hackt, oder auch einen anderen Vorschlag für das besagte Problem bringen!
    Ich danke um voraus und bitte meine Anfänger-Unwissenheit zu entschuldigen!
    Gruß,
    Lin



  • gegenfrage: gibts ein geräusch, wenn im wald ein baum umfällt?



  • Wo es hackt kann ich dir jetzt nicht sagen, aber einen Vorschlag hätte ich:

    ...
    while ((c = fgetc (file)) != EOF) {
        if (c == seq[i++]) // 'seq' ist die zu suchende Sequenz
            if (++k == strlen (seq))
                count++;
            else
                continue;
        i = k = 0;
    }
    ...
    

    Gez. monstermunchkin



  • Hallo!
    U.a. im Garten soll es ja öfter mal hacken 😃 *scnr*

    Mit deinem Programm legst du dich zu dolle in der Zeichenlänge fest und es funzt nur für eine bestimmte Zeichenfolge.
    Du könntest es in der Länge und in der Anzahl etwas variabler gestalten.
    Ich habs mal mit Buchstaben gemacht, geht aber prinzipiell mit beliebigen Zeichen:

    #define TOKEN_MAXLEN 64
    char* tokens[] = {"Fritze", "fischt", "Fische", NULL};
    
    int shit_happens( char* s )
    {
    	fprintf ( stderr, "%s: %s\n", s, strerror(errno) );
    	return 1;
    }
    
    void is_word_token ( char* word )
    {
    	char** p = tokens;
    	while(*p)
    	{
    		if ( strcmp ( *p, word ) == 0 )
    			break;
    		p++;
    	}
    
    	if (*p)
    		printf ( "%s is a token.\n", word );
    	else
    		printf ( "%s is not a token.\n", word );
    }
    
    int main() 
    { 
    	char* fname = "test.txt";
    	char buf[TOKEN_MAXLEN+1] = {0};
    	int i = 0, c = 0;
    
    	FILE* fp = fopen ( fname, "r" );
    	if ( fp == NULL )
    		return shit_happens(fname);
    
    	while ( (c = fgetc(fp)) != EOF )
    	{
    		if ( i < TOKEN_MAXLEN && isalpha(c) )
    		{
    			buf[i++] = c;
    		}
    		else
    		{
    			if ( i == 0 )
    				continue;
    			 i = buf[i] = 0;
    			is_word_token (buf);		}
    	}
    	fclose(fp);
    	return 0;
    }
    

    Der Dateiinhalt der Testdatei ist hier

    Fischers Fritze fischt frische Fische.
    Frische Fische fischt fischers Fritze.

    :p

    Gruß,
    B.B.



  • Und wenn man es dann vernünftig machen will, nimmt man auch gleich ein gescheiten Algorithmus:

    http://de.wikipedia.org/wiki/Knuth-Morris-Pratt-Algorithmus

    🙂



  • In der Zwischenzeit habe ich folgende Lösung gefunden:

    ...
    char text[4] = {'a','b','c','d'};
    char buf[4] = {0,0,0,0};
    
    buf[0]=(char)fgetc (pFile);
    buf[1]=(char)fgetc (pFile);
    buf[2]=(char)fgetc (pFile);
    buf[3]=(char)fgetc (pFile);
    if ((buf[0]==text[0])&&(buf[1]==text[1])&&(buf[2]==text[2])&&(buf[3]==text[3])){
    	count++;
    }
    do {
    	buf[0]=buf[1];
    	buf[1]=buf[2];
    	buf[2]=buf[3];
    	buf[3]=(char)fgetc (pFile);
    	c=(int)buf[3];
    	if ((buf[0]==text[0])&&(buf[1]==text[1])&&(buf[2]==text[2])&&(buf[3]==text[3])){
    		count++;
    	}
    }while (c!= EOF);
    ...
    

    jetzt kommen die nächsten Schwierigkeiten, werde mich bestimmt bald wieder melden!

    Gruß,

    Lin



  • lin123 schrieb:

    In der Zwischenzeit habe ich folgende Lösung gefunden:

    if ((buf[0]==text[0])&&(buf[1]==text[1])&&(buf[2]==text[2])&&(buf[3]==text[3]))
    	count++;
    

    das geht aber einfacher:

    if(memcmp(buf, text, 4) == 0)
      ...
    

Log in to reply