web-dev-qa-db-fra.com

Valeur de retour de fgets ()

Je viens de commencer à travailler avec I/O Dans C. Voici ma question -
J'ai un fichier, à partir duquel je lis mon entrée. Ensuite, j'utilise fgets() pour obtenir des chaînes dans un tampon que j'utilise d'une manière ou d'une autre. Maintenant, que se passe-t-il si l'entrée est trop courte pour le tampon, c'est-à-dire si la première lecture par fgets() atteint EOF. fgets() doit-elle renvoyer NULL (comme je l'ai lu dans la documentation de fgets())? Il semble que non et j'obtiens correctement mon avis. D'ailleurs, même ma feof(input) ne dit pas que nous avons atteint EOF.
Voici mon extrait de code.

char    buf[BUFSIZ];
FILE    *input,
        *output;

input   = fopen(argv[--argc], "r");
output  = fopen(argv[--argc], "w");

/**
 *  If either of the input or output were unable to be opened
 *          we exit
 */
if (input == NULL) {
    fprintf(stdout, "Failed to open file - %s.\n", argv[argc + 1]);
    exit(EXIT_FAILURE);
}

if (output == NULL) {
    fprintf(stdout, "Failed to open file - %s.\n", argv[argc + 0]);
    exit(EXIT_FAILURE);
}

if (fgets(buf, sizeof(buf), input) != NULL) {
    ....
}

/**
 *  After the fgets() condition exits it is because, either -
 *      1) The EOF was reached.
 *      2) There is a read error.
 */
if (feof(input)) {
    fprintf(stdout, "Reached EOF.\n");
}
else if (ferror(input)) {
    fprintf(stdout, "Error while reading the file.\n");
}
11
yadav_vi

La documentation de fgets() ne dit pas ce que vous pensez qu'elle fait:

Depuis ma page de manuel

fgets() lit au plus un caractère de moins de size dans le flux et les stocke dans le tampon pointé par s. La lecture s'arrête après un EOF ou une nouvelle ligne. Si une nouvelle ligne est lue, elle est stockée dans le tampon. Un octet nul final ('\0') Est stocké après le dernier caractère du tampon.

Et ensuite

gets() et fgets() retourne s en cas de succès et NULL en cas d'erreur ou lorsque la fin du fichier se produit alors qu'aucun caractère n'a été lu.

Je ne lis pas cela comme disant qu'un EOF sera traité comme une condition d'erreur et renverra NULL. En effet, il indique qu'un NULL ne se produirait que lorsque EOF se produit lorsque aucun caractère n'a été lu.

Le standard POSIX (qui diffère du standard C moins accessible) est ici: http://pubs.opengroup.org/onlinepubs/009695399/functions/fgets.html et indique:

En cas de réussite, fgets() renverra s. Si le flux est en fin de fichier, l'indicateur de fin de fichier pour le flux doit être défini et fgets() doit retourner un pointeur nul. Si une erreur de lecture se produit, l'indicateur d'erreur pour le flux doit être défini, fgets() doit retourner un pointeur nul et doit définir errno pour indiquer l'erreur.

Cela indique clairement qu'il ne retournera un NULL que s'il est en fait à EOF lorsqu'il est appelé, c'est-à-dire si des octets sont lus, il ne renverra pas NULL.

15
abligh