[C] Contare righe in un file

Obidream
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:

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 :-D

Risposte
apatriarca
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?

Obidream
Il mio file testo contiene una lista di nomi messi in questo modo:
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

apatriarca
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.

Obidream
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);
}

apatriarca
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.

Obidream
Grazie, in effetti ho risolto in questo modo... mi ero dimenticato di rimettere il -1 nell'if..
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;
}

vict85
Ma se il nome è una singola parola perché non conti semplicemente il numero di parole? Per esempio così:
[...]
#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

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 :-D ( sono maledetti nick di un gioco online)

vict85
"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 :-D ( sono maledetti nick di un gioco online)


In questo caso puoi usare isgraph

claudio862
"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 :-D ( sono maledetti nick di un gioco online)


In questo caso puoi usare isgraph[/quote]

O anche ! isspace()

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.