Newsgroup: it.comp.lang.c
Titolo: Scansione su file dati

Ho un file di testo con una serie di numeri tabulati in un dato formato, in
migliaia di righe. Del tipo:
1 353 5.00e-4 53.3
2 353 5.00e-4 53.3
3 353 5.00e-4 53.3
4 353 5.00e-4 53.3
5 353 5.00e-4 53.3
....etc..
dove la prima colonna e' l'indice del numero di riga.
Ora dovrei fare una funzione che apre il file, pesca la riga N-esima (N
parametro input) e legge i valori.
Per selezionare la riga i-esima potrei fare un loop che esegue una scansione
riga per riga, controllando l'indice (prima colonna) fino a che non risulta
uguale a quello desiderato. Oppure questo controllo posso farlo direttamente
sulla variabile del loop, cioe' del tipo:
void PAgaga(int N){
 // 1-apro il file
 FILE* file= fopen("filename.dat","r");
 // 2-eseguo il loop
 for(int ii=0;ii<NTOT;ii++){
 // 3-qui leggo la riga ii-esima
 // 4-registro i valori della riga N-esima
 if(ii!=N){
  etc.etc. etc..
 }
}
Vorrei pero' sapere se esiste un metodo (che sarebbe forse piu' veloce) per
leggere direttamente la riga i-esima senza dovere fare la scansione su tutte
le righe..
--------------------------------
Inviato via 
http://arianna.libero.it/usenet/

 le righe..
Se le righe hanno tutte la stessa lunghezza basta che fai il conto di 
quanti byte devi saltare per andare alla riga che ti interessa e pace.
Se invece le righe sono diseguali puoi andare a tentativi: un metodo per 
righe assolutamente diseguali consiste nel piazzare il punto di lettura 
al centro del file, leggere caratteri fino ad un marcatore EOL, leggere 
il numero di riga e decidere il prossimo passo, che sarebbe leggere ad 
un quarto o a tre quarti e così via.
Spero ti sia d'aiuto, non ho tempo per dilungarmi in dettagli ed esempi 
di codice.
-- 
  Francesco S. Carta
 
http://fscode.altervista.org


se ti serve una specie di accesso random, potresti scrivere un loop che
legga carattere per carattere e a ogni carattere "\n" ne piazzi la
posizione in un array. Avresti una specie di indicizzazione degli inizi
linea e potrai cavartela con le varie "fseek" e soci. In genere, in casi
come questi io preferisco leggere tutto e schiaffare dati in qualche
struttura dati.
ciao
Apx.


Se le righe hanno tutte sempre la stessa dimensione e se i numeri di
riga sono sequenziali (ovvero la riga 3 corrisponde alla terza riga
del file fisico) certo, basta un fseek (o una lettura con pwrite(), se
sei su un sistema posix). Se invece i numeri di riga non corrispondono
devi effettuare una vera e propria ricerca: io mapperei il file in
memoria (mmap()/MapViewOfFile()) e ci darei di quicksort (o simili, a
seconda di quanti e quali dati hai). Se, come terza opzione, le righe
hanno anche dimensione differente non c'è maniera se non con un
aproccio euristico (leggo un po' qua un po' là a seconda di come penso
siano messi i dati), caso in cui l'approccio migliore è sicuramente
leggersi tutto e creare un altro file di indice per accessi
successivi.
Ciao!

 le righe..
Dipende molto in effetti dal numero di accessi che devi fare al file.
Se ti serve di leggere molte righe alla volta, nella durata di tutto
il programma, forse è meglio mappare un fantastico array di stringhe
in memoria. In ogni caso, detta EOL la stringa di fine linea in
Unix, "\n", o su Windows, "\r\n", la riga N-esima è l'array di caratteri
che parte dall'(N-1)-esima EOL (esclusa), all'N-esima EOL (esclusa),
eccezion fatta per la prima riga (che non è preceduta da EOL.
ps: assicurati che l'ultima riga sia seguita da una EOL);
-- 
Non puoi insegnare qualcosa ad un uomo. You cannot teach a man anything.
Lo puoi solo aiutare   --  Galileo  Galilei  --   You can only help him
a scoprirla dentro di sé.                        discover it in himself.
Vincenzo Mercuri

 ps: assicurati che l'ultima riga sia seguita da una EOL);
Grazie (a tutti); anche io in generale tendo a caricare tutto in
memoria, ma in questo caso non avrebbe senso perché il mio programma,
ad ogni esecuzione, legge una e una sola riga in tutto. Quale sia la
riga da leggere poi dipende (il n. di riga è un argomento
dell'eseguibile), ma sarebbe inutile tenerle tutte in memoria.
Comunque il tempo lettura del file e' piccolo rispetto all'esecuzione
del resto del programma, per cui ho deciso di fare il loop fino ad
arrivare alla riga desiderata, evitando cosi' di dover giocare con i
bit.