Newsgroup: it.comp.lang.c
Titolo: Ricerca Stringa su File

Buongiorno a tutti,
premetto di essere un principiante in C.
Ma non riesco a risolvere il seguente problema:
sto cercando di fare una
funzione che va a cercare in un file di testo(alfanumerico) una parola e
voglio
ritornare una lista con tutte le parole seguenti a questa parola cioč.
Input:
-file alfanumerico
"Oggi pomeriggio antonio bianchi ha parlato con antonio rossi che č nato 15
anni prima di antonio verdi"
-parola da cercare "antonio"
Output
"bianchi"->"rossi"->"verdi"
Non so se esiste gia una find (tipo grep) per il C?
cosa mi consigliate?
grazie
dav
--------------------------------
Inviato via 
http://arianna.libero.it/usenet/

 cosa mi consigliate?
Varie possibilità. La più semplice è caricare tutto il file in memoria
(facendo una grassa malloc e poi leggendolo tutto) e poi usare le funzioni
del C (tipo strstr), e poi fare un paio di controlli aggiuntivi (strstr
infatti non ti garantisce che quello che trova sia una parola. Se cerco
pippo allora lui mi troverà il pippo contenuto in xxxpippoxxx. Sta a me poi
vedere se la parola pippo è una parola intera (cioè è preceduta da un
terminatore di parole e seguita da un terminatore di parole).
Terminatori di parole tipici sono: <punteggiatura (.,;:?!)<spazio><\n><\r>).
Poi devi solo trovare la parola successiva (quindi trovare la fine della
prima parola, eliminare tutti i seguenti terminatori di parola (potresti
avere un doppio spazio dopo la parola), poi scoprire dove finisce la parola
successiva (trovare il primo terminatore dopo il primo non terminatore) e
stampare la parola risultante)
--- bye

 Varie possibilità. La più semplice è caricare tutto il file in memoria
Ok..grazie per l'idea, ma come faccio a caricare il file in memoria?Scusa se
ti rompo...mauna tua spiegazione mi farebbe imparare una cosa nuova!
grazie
Dav


 Dav
Leggi la dimensione del file (lasciata come facile esercizio all'OP ;-))
fileInMemP = malloc(fileDim);
if(NULL != fileInMemP)
  res = fread(fileInMemP, fileDim, 1, fileP);
if(res != fileDim)
  ...
in alternativa allochi un certa dimensione, se il file e' piu' grande
riallochi (eventualmente iterando la cosa). 
HTH
C:\>iao Angelo
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG

Ok..grazie mille!


Secondo me non è il metodo migliore perchè ti vai ad impelagare in cose che
ti faranno navigare con una barca a remi in un bosco.
Se il tuo file non ha sempre una precisa dimensione va gestito.
Se il file non si può caricare completamente va gestito.
Quel metodo è il migliore quando devi cercare delle cose che ti impongono
un'alta frequenza di lettura nel file e di ricerche a ritroso ma questo non
è il tuo caso. Ti conviene scriverti una routine di ricerca e prendere la
parola successiva. Mal che ti vada puoi rischiare il caso in cui la parola
che tiri su sia di nuovo quella che cerchi e allora va gestito. In tutti e
due i casi il file lo devi leggere una sola volta e se usi la gestione stram
sarà veloce uguale.

 sarà veloce uguale.
Vero. Ma per farlo "bene" (con tutti i crismi) diventa più complicato. Lui
voleva una soluzione semplice. Perdendoci un po' di tempo potrei anch'io
trovare una soluzione "ottimizzata" (ma alla fin fine probabilmente farei
una cosa system-dependant usando le memory map e fregandomene altamente dei
files di testo troppo grossi per essere mappati in memoria. Tanto non si
vedono tanti files di testo > 64mb)
--- bye

> Leggi la dimensione del file (lasciata come facile esercizio all'OP ;-))
Sei cattivo! Sai benissimo che non esiste nessuna funzione "standard" per
scoprire la dimensione del file:
fseek(filepointer, 0, SEEK_END);
long lFileSize = ftell(filepointer);
fseek(filepointer, 0, SEEK_SET);
Suggerimento: ti conviene aprire il file in modalità binaria. Andrà un
pochino più veloce. Tanto a te dei fine linea non te ne frega niente.
--- bye

 (facendo una grassa malloc e poi leggendolo tutto) e poi...
<cut>
Non si potrebbe leggere parola per parola e fare ogni volta i vari 
controlli, fino alla fine del file?
In questo modo il codice diventerebbe indipendente dalla lunghezza del file.
Marcello


Parola per parola no. Al massimo carattere per carattere. Il problema però è
che così sarebbe più lento (la lettura carattere per carattere è più lenta
della lettura bufferizzata e leggere tutto il file in un blocco solo è
probabilmente l'estremizzazione della lettura bufferizzata). Avendo tempo e
capacità la soluzione migliore è la lettura a pacchetti (diciamo 4kb) e poi
l'analisi del contenuto di ogni pacchetto. C'è inoltre da considerare che la
ricerca di una sottostringa in una stringa fatta in maniera "banale"
(confronta il primo carattere, poi il secondo ecc.) è più lenta della
ricerca che può fare la strstr (esiste un algoritmo migliore... Mi sembra
parta dall'ultimo carattere e poi proceda a ritroso)
--- bye