[C] Contare righe in un file
Salve a tutti, come da titolo mi servirebbe trovare un modo per contare le righe in un file di testo e poi leggerle con la fgets 
La prima idea che ho avuto è stata fare una cosa del genere:
E poi:
Tuttavia ho riscontrato 2 problemi... Il primo era la presenza di '\n' messi a casaccio e che quindi avrebbero incrementato il numero di righe; l'ho risolto con un controllo di questo tipo:
if(strlen(nick)>1)
Però rimane il secondo problema, perché l'utente potrebbe sempre inserire una serie di blank e quindi generarmi una riga di spazi bianchi che la fgets andrebbe comunque a leggere...avevo pensato di ovviare al problema con questa funzione:
e quindi modificare l'if di sopra in questo modo:
if((strlen(nick)>1)&&(void_stringa(nick)==FALSE))
ma non ho ottenuto nulla...
Tutti i consigli sono ben accetti

La prima idea che ho avuto è stata fare una cosa del genere:
k=0; while((c=getc(lista))!=EOF) { if(c=='\n') k++; }
E poi:
for(i=0;i<(k);i++) { fgets(nick,MAX_STR,lista); nick[strlen(nick)-1]='\0'; //operazioni sulla stringa nick }
Tuttavia ho riscontrato 2 problemi... Il primo era la presenza di '\n' messi a casaccio e che quindi avrebbero incrementato il numero di righe; l'ho risolto con un controllo di questo tipo:
if(strlen(nick)>1)
Però rimane il secondo problema, perché l'utente potrebbe sempre inserire una serie di blank e quindi generarmi una riga di spazi bianchi che la fgets andrebbe comunque a leggere...avevo pensato di ovviare al problema con questa funzione:
boolean void_stringa(char str[]) { unsigned int i,cont=0; for(i=0;i<strlen(str);i++) if(str[i]==' ') cont++; if(cont==strlen(str)) return TRUE; else return FALSE; }
e quindi modificare l'if di sopra in questo modo:
if((strlen(nick)>1)&&(void_stringa(nick)==FALSE))
ma non ho ottenuto nulla...
Tutti i consigli sono ben accetti

Risposte
Io credo che il problema non sia tanto il codice, ma nella tua definizione di che cosa sia una "riga" del file di testo. Normalmente non ha infatti alcuna importanza se le righe sono vuote, piene di spazi o di qualsiasi altra cosa per considerarle righe del file. Per cui, che cosa stai cercando di leggere dal file? Che cos'è una riga del tuo file? Come deve essere fatta? Per quale ragione devi sapere il numero di righe prima di leggerle?
Il mio file testo contiene una lista di nomi messi in questo modo:
Il mio problema è questo:
se l'utente scrive i nomi così:
mi ritrovo una stringa che contiene solo il '\0' e che io vorrei possibilmente scartare... idem se una stringa è fatta da soli spazi bianchi... Quindi pensavo di contare le stringhe che rispettano questi criteri e leggerle.. Tra l'altro per la stringa contenente il '\0' ho risolto il problema, quindi mancherebbe solo quello delle righe con soli spazi bianchi
Pippo Gianfranco Roberto etc
Il mio problema è questo:
se l'utente scrive i nomi così:
Pippo Gianfranco
mi ritrovo una stringa che contiene solo il '\0' e che io vorrei possibilmente scartare... idem se una stringa è fatta da soli spazi bianchi... Quindi pensavo di contare le stringhe che rispettano questi criteri e leggerle.. Tra l'altro per la stringa contenente il '\0' ho risolto il problema, quindi mancherebbe solo quello delle righe con soli spazi bianchi
I nomi possono contenere spazi? Quello che puoi fare è probabilmente eliminare tutti gli spazi bianchi a inizio e fine della riga. A questo punto verifichi se la lunghezza della stringa è zero e in questo caso scarti la stringa.
Quindi a questo punto converrebbe implementare una funzione del genere per leggere da file?
int leggi_nick( char str[]) { int indice, carat; indice=0; while(((carat=getchar())!='\n')) { if(carat==' ') { // non fare nulla se il carattere è un blank } else if(indice<MAX_STR) { str[indice]=(char)carat; indice++; } } str[indice]='\0'; return(carat); }
Ma dipende da cosa vuoi fare.. Quella funzione scarta tutti gli spazi dalla riga, anche quelli in messo ai nomi (che fai se ci sono due nomi nella stessa riga separata da spazi?), però non scarta altri tipi di spazi come la tabulazione.
Grazie, in effetti ho risolto in questo modo... mi ero dimenticato di rimettere il -1 nell'if..
Ora fa quel che deve in effetti
Ora fa quel che deve in effetti
boolean void_stringa(char str[]) { unsigned int i,cont=0; for(i=0;i<strlen(str);i++) if(str[i]==' ') cont++; if(cont==(strlen(str)-1)) return TRUE; else return FALSE; }
Ma se il nome è una singola parola perché non conti semplicemente il numero di parole? Per esempio così:
Comunque leggere due volte il file non mi sembra una cosa molto efficiente.
P.S.: non ho testato il codice
[...] #include <ctype.h> [...] k=0; { int b = 0; while((c=fgetc(lista))!=EOF) { if( isalpha(c) ) { if(b == 0) { b=1; ++k; } } else { if(b != 0) b = 0; } } } [...]
Comunque leggere due volte il file non mi sembra una cosa molto efficiente.
P.S.: non ho testato il codice
E' vero, devo provare questo approccio al problema appena ho tempo! L'unica cosa che non farei è controllare se il carattere è alfabetico, in quanto può contenere numeri o _ ? . e cose varie
( sono maledetti nick di un gioco online)

"Obidream":
E' vero, devo provare questo approccio al problema appena ho tempo! L'unica cosa che non farei è controllare se il carattere è alfabetico, in quanto può contenere numeri o _ ? . e cose varie( sono maledetti nick di un gioco online)
In questo caso puoi usare isgraph
"vict85":
[quote="Obidream"]E' vero, devo provare questo approccio al problema appena ho tempo! L'unica cosa che non farei è controllare se il carattere è alfabetico, in quanto può contenere numeri o _ ? . e cose varie( sono maledetti nick di un gioco online)
In questo caso puoi usare isgraph[/quote]
O anche ! isspace()