Problema com 'fgets' em C

FELiYCORA

1st Folding then Sex
Boas, tou com o seguinte problema num programa que estou a desenvolver em C:

Neste troço de código, o programa deve ler as linhas de um ficheiro de texto uma a uma (isso está a ser conseguido) e passar a string para dentro de uma função que a decompõe e processa. O problema neste troço de código é que a variável aux nunca fica com o valor NULL e não estou a perceber porquê, ou seja, se o teste_comando não retornar 0 o ciclo nunca acaba e pelo resultado do programa, ele fica sempre a ler a última linha. Porque é que o fgets não me está a devolver NULL?

O ficheiro tem este formato:

DEPEND 3 2
DEPEND 2 0
INSTALL 3

Ele faz tudo bem mas fica sempre a ler a última linha em vez de acabar o ciclo, a não ser que eu na linha seguinte do ficheiro escreva END, que é o comando que faz com que a função teste_comando retorne 0.

Obrigado desde já.

Código:
case 3:  

      ficheiro = fopen(argv[2], "r");
      if(ficheiro == NULL)
      {
        printf("Erro ao abrir ficheiro");
      }

      do
      {
        aux = fgets(linha, DIMV, ficheiro);

    
        switch(teste_comando(linha, &arg1, &arg2))
        {
          case 2:
      
            matriz [arg1] [0] = arg2;
            break;
    
          case 1:
    
            install (arg1, matriz);
            break;
            
          case 0:
          
            fim = 1;
            exit(0);
      
          default:
            break;
         }
       }
       while ( (aux != NULL) || (fim != 1) );
       
       fclose(ficheiro);
       argc = 1;
       break;
 
Porque o fgets nunca retorna NULL. Quando muito retorna 0 (o fgets retorna o numero de char's que leu).
A condição que queres tem de ser feita com em função do fgets > 0 ou atraves do feof()
 
boas, obrigado pela resposta, mas não é isso que o man fgets diz:

RETURNS
`fgets' returns the buffer passed to it, with the data filled in. If
end of file occurs with some data already accumulated, the data is
returned with no other indication. If no data are read, NULL is
returned instead.
 
o melhor é utilizar feof()...

Um exemplo utilizado numa aula de ASC1:

Código:
void send_file(char *file)
{
  unsigned char s;
  FILE *f = fopen(file, "r");
  while(!feof(f))
  {
   s = fgetc(f);
   send_serial(s);
   printf("%c",s);
  }
  fclose(f);
}

ou seja vai lendo o ficheiro (no caso carácter a carácter para enviar pela porta série [é um exercício de I/O]) até chegar ao fim do ficheiro...

cumps
 
Última edição:
acontece o mesmo... :(

já agora nao percebi o ! antes do feof(f)

O ! nega o valor.

O teu programa entra em ciclo infinito porque tens a condição do while mal.

Onde tens :
Código:
 while ( (aux != NULL) || (fim != 1) );


deve estar :
Código:
 while ( (aux != NULL) && (fim != 1) );
 
não, senão o ciclo só terminava quando as duas condiçoes fossem verdadeiras, e eu quero que termine quando qualquer uma delas for verdadeira...
 
Código:
 while ( (aux != NULL) || (fim != 1) );
Tomemos condição por "(aux != NULL) || (fim != 1) "

O while executa enquanto a condição se mantem verdadeira, e termina quando esta tiver um valor Falso.

Ora , imagina que a aux toma a valor NULL ( ie. já leu o ficheiro todo) mas não encontrou a palavra END ( ou seja, fim != 1 )

assim sendo a condição do while, neste momento, é esta "Falso ou Verdadeiro", que como deves saber dá verdadeiro, logo o while vai entrar en ciclo infinito.
 
Porque não utilizas somente o
while(fgets(linha, DIMV, ficheiro)!=NULL)&&(fim != 1))
{
....
}
em vez do do while?senão levas com asneiras no linha quando chegas ao fim do ficheiro..E o eXn tem toda a razão se queres que o ciclo termine quando um deles for falso terás de colocar &&...
 
Última edição:
Porque não utilizas somente o
while
(fgets(linha, DIMV, ficheiro)!=NULL)&&(fim != 1))
{
....
}
em vez do do while?senão levas com asneiras no linha quando chegas ao fim do ficheiro..E o eXn tem toda a razão se queres que o ciclo termine quando um deles for falso terás de colocar &&...

Yep. Para funcionar como tinhas acho que a variavel aux teria que ser do tipo apontador (para receber um NULL) para ficheiro, ou seja: FILE *aux, o que não deve ser o caso. Mas acho que é trabalho desnecessário estar a declarar a var propositadamente, podes ter como condição do ciclo: fgets(linha, DIMV, ficheiro) != NULL :)
 
Obrigado eXn, tinhas razão e esse era o erro.

Cesaria obrigado também, tens razão, é mais simples fazer como tu disseste, já alterei.

MaxDamage, a variavel aux era do tipo apontador para caracter, aliás se não fosse, o compilador daria erro.

Está resolvido obrigado a todos.
 
Back
Topo