web-dev-qa-db-fra.com

Atteindre EOF avec fgets

J'écris une fonction qui effectue des actions d'authentification. J'ai un fichier avec tous les user_id:password:flag couples structurés comme ceci:

Users.txt

user_123:a1b2:0 user_124:a2b1:1 user_125:a2b2:2

Voici le code:

int main(){
    /*...*/

    /*user_id, password retrieving*/
    USRPSW* p = malloc(sizeof(USRPSW));
    if(p == NULL){
        fprintf(stderr, "Dynamic alloc error\n");
        exit(EXIT_FAILURE);
    }
    memset((void*)p, 0, sizeof(USRPSW));

    if(usr_psw_read(acc_sock_ds, p->user_id, USR_SIZE) <= 0){
        printf("Failed read: connection with %s aborted.\n",
                 inet_ntoa(client_addr.sin_addr));
        close(acc_sock_ds);
        continue;
    }

    if(usr_psw_read(acc_sock_ds, p->password, PSW_SIZE) <= 0){
        printf("Failed read: connection with %s aborted.\n",
                 inet_ntoa(client_addr.sin_addr));
        close(acc_sock_ds);
        continue;
    }

    /*Authentication through user_id, password*/
    FILE *fd;
    fd = fopen(USERSFILE, "r");
    if(fd == NULL){
        fprintf(stderr, "Users file opening error\n");
        exit(EXIT_FAILURE);
    }

    char *usr_psw_line = malloc(USR_SIZE+PSW_SIZE+3+1);
    if(usr_psw_line == NULL){
        fprintf(stderr, "Dynamic alloc error\n");
        exit(EXIT_FAILURE);
    }

    while(1){

        memset((void*)usr_psw_line, 0, sizeof(USR_SIZE+PSW_SIZE+3+1));
        fgets(usr_psw_line, USR_SIZE+PSW_SIZE+3+1, fd);
        printf("%s\n", usr_psw_line);
        fseek(fd, 1, SEEK_CUR);


        /*EOF management*/
        /*usr_id - password matching checking */

    }   
/*...*/    
}

Comment puis-je gérer la EOF atteinte? J'ai vu que lorsque EOF est atteint fgets ne modifie plus la ligne usr_psw_line mais ne retourne ni Pointeur NULL. Si EOF est atteint, cela signifie qu'aucune correspondance n'est trouvée dans le fichier utilisateurs et que la boucle est interrompue.

Quelqu'un peut-il me donner quelques conseils ou suggestions?

11
Fabio Carello

fgets() retourne un pointeur nul lorsqu'il atteint la fin du fichier ou une condition d'erreur.

(EOF est une macro qui spécifie la valeur renvoyée par certaines autres fonctions dans des conditions similaires; ce n'est pas seulement une abréviation pour l'expression "fin de fichier".)

Vous ignorez le résultat renvoyé par fgets(). Ne fais pas ça.

Notez que la simple vérification de feof(fd) ne fera pas ce que vous voulez. feof() renvoie un vrai résultat si vous avez atteint la fin du fichier. Si vous rencontrez une erreur à la place, feof() renvoie toujours false, et vous avez une boucle infinie si vous utilisez feof() pour décider quand vous avez terminé. Et cela ne retourne vrai que après vous n'avez pas réussi à lire l'entrée.

La plupart des fonctions d'entrée C renvoient une valeur spéciale pour indiquer qu'il n'y a plus rien à lire. Pour fgets() c'est NULL, pour fgetc() c'est EOF, et ainsi de suite. Si vous le souhaitez, vous pouvez appeler feof() et/ou ferror() pour déterminer pourquoi il n'y a plus rien à lire.

21
Keith Thompson

Vous voudrez peut-être essayer quelque chose comme ça dans votre boucle:

while(1)
{
    memset((void*)usr_psw_line, 0, sizeof(USR_SIZE+PSW_SIZE+3+1));
    if( !fgets(usr_psw_line, USR_SIZE+PSW_SIZE+3+1, fd)
     || ferror( fd ) || feof( fd ) )
    {
        break;
    }
    printf("%s\n", usr_psw_line);
    fseek(fd, 1, SEEK_CUR);

    /*EOF management*/
    /*usr_id - password matching checking */

}

Avec le code supplémentaire, la boucle se terminera si fgets renvoie NULL (plus de données à lire) ou si vous lisez la marque EOF ou si vous avez eu une erreur dans le fichier Je suis sûr que c'est exagéré, mais ces tests ont toujours fonctionné pour moi.

3
Steve Valliere