Newsgroup: it.comp.lang.c
Titolo: Grep - HELP!

Ciao. Devo scrivere, per passare un esame universitario, una "sotto-grep",
ovvero una funzione che si comporti come la grep e ne abbia alcune opzioni.
Qualcuno potrebbe darmi una mano? Darmi delle indicazioni e dei
suggerimenti?
Grazie


Cercando, dovrebbe esserci disponibile il sorgente in rete, da qualche
parte.
Anzi, se hai Linux, dovresti gią averlo, sempre da qualche parte.
--
Alessandro Monti

nomefileout
   opzioni  : i    esegue una ricerca case insensitive
              n    mostra i numeri di linea
              c    conta soltanto le [non-]occorrenze
              v    considera solo le non-occorrenze
   ---------
   compilato con DJGPP
   17/11/1999 Andrea Laforgia 
   (ore 2.19 di notte, siate clementi circa gli errori ! ;)
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
static int case_flag = 1 ;       /* case sensitive */
static int lines_flag = 0 ;      /* mostra i numeri di linea */
static int count_only_flag = 0 ; /* conta soltanto le [non-]occorrenze
*/
static int nomatch_flag = 0 ;    /* considera le non-occorrenze */
static unsigned line_count ;
static unsigned line_idx ;
int checkstrings ( const char *str, const char *substr )
{
    size_t l1 = strlen( str ) ;
    size_t l2 = strlen( substr ) ;
    char *s1 = malloc( l1 + 1 ) ;
    char *s2 = malloc( l2 + 1 ) ;
    int i, r ;
    strcpy( s1, str ) ;
    strcpy( s2, substr ) ;
    if ( case_flag == 0 )
    {
       for ( i = 0 ; i < l1 ; i++ )
           s1[i] = tolower( s1[i] ) ;
       for ( i = 0 ; i < l2 ; i++ )
           s2[i] = tolower( s2[i] ) ;
    }
    r = (int) strstr( s1, s2 ) ;
    free( s1 ) ;
    free( s2 ) ;
    return ( r ) ;
}
void write( char * s, unsigned n )
{
     if ( !count_only_flag )
     {
        if ( lines_flag )
           printf( "%d :", n ) ;
        printf( "%s", s ) ;
     }
}
int main( int argc, char *argv[] )
{
    int j, r ;
    char searchstring[100], line[100] ;
    if ( argc > 1 )
    {
       if ( argv[1][0] == '-' )
       {
          for ( j = 1 ; argv[1][j] ; j++ )
          {
              switch ( argv[1][j] )
              {
                     case 'i' : case_flag = 0 ; break ;
                     case 'n' : lines_flag = 1 ; break ;
                     case 'c' : count_only_flag = 1 ; break ;
                     case 'v' : nomatch_flag = 1 ; break ;
                     default  : printf( "warning : invalid option
\'%c\'\n", argv[1][j] ) ;
                                break ;
              }
          }
       }
       else strcpy( searchstring, argv[1] ) ;
    }
    if ( argc > 2  && *searchstring != 0 )
    {
       strcpy( searchstring, argv[2] ) ;
    }
    line_idx = 0 ;
    line_count = 0 ;
    while ( fgets( line, sizeof line, stdin ) )
    {
          r = checkstrings( line, searchstring ) ;
          if ( ( r == 0 && nomatch_flag == 1 ) ||
               ( r != 0 && nomatch_flag == 0 ) )
          {
             write( line, line_idx ) ;
             ++line_count ;
          }
          line_idx ++ ;
    }
    if ( count_only_flag )
    {
       printf( "%d\n", line_count ) ;
    }
    return 0 ;
}
--
Andrea Laforgia        (
andrea_...@bigfoot.com
)

 Grazie
Per la seconda volta torno a consigliare il libro di Robert Sedgewich.
E' trattato un automa a stati finiti non deterministico per il ricono-
scimento delle espressioni regolari e volendo anche gli algoritmi di
Morris e Boyer-Moore per le stringhe semplici.
Librerie in sorgente per il riconoscimento delle espressioni regolari
se ne trovano a volonta', ma l' algoritmo e' interessante da
comprendere.
Ci sono versioni ricorsive (le implementazioni piu' semplici, ma non
ottimiz-
zabili) che praticamente "esplorano" tutte le possibili uscite dal
modello
(pattern) del flusso di input. Non e' necessario amministrare alcuno
stack
visto che le chiamate ricorsive fanno uso di quello di sistema. Questa
soluzione non e' molto apprzzata perche' per sua natura deve procedere
con
l' input per vedere se si arriva ad una corrispondenza del testo con il
pattern e, in caso contrario, tornare indietro e utilizzare l' input
memoriz-
zato per tentare altre vie. Il proposito e' quello di verificare tutte
le
possibilita' ad ogni carattere di input. Si usa quindi una coda doppia,
a cui si puo' accedere come stack o come coda per tenere traccia dello
stato
di ogni diramazione (cioe di ogni uso del costrutto OR o chiusura). E'
una simu-
lazione di una macchina NON DETERMINISTICA.
Sul Sedgewich trovi illustrazioni molto esplicative.
(Precisazione: non prendo soldi dalla Addison Wesley)
Ciao.