fgets(3)

Fonction de la bibliothèque C

Lit une ligne dans un tableau sans dépasser sa taille, garde le \n et termine toujours la chaîne. Renvoie NULL à la fin du fichier ou en cas d'erreur.

Synopsis
#include <stdio.h>
char *fgets(char *restrict s, int n, FILE *restrict stream);

Description

fgets lit des caractères sur stream et les range dans s, jusqu'à n - 1 au plus. Elle s'arrête après un \n, qu'elle garde dans le tableau, ou à la fin du fichier, et ajoute toujours un '\0' après le dernier caractère lu. Elle ne peut donc pas déborder d'un tableau dont tu lui donnes la vraie taille, ce qui en fait la façon sûre de lire une ligne. Sa vieille cousine gets, qui ne connaissait pas la taille du tableau, a été retirée de la norme en C11.

Pour lire au clavier, stream vaut stdin.

Valeur de retour

s si au moins un caractère a été lu. NULL si la fin du fichier arrive avant le premier caractère, ou en cas d'erreur. D'où la boucle classique : while (fgets(ligne, sizeof ligne, stdin) != NULL).

Pièges

  • Le \n reste dans la chaîne. Pour l'enlever, quelle que soit la longueur de la ligne : ligne[strcspn(ligne, "\n")] = '\0';.

  • Une ligne plus longue que le tableau est coupée, et la suite arrive à l'appel suivant, comme dans l'exemple. L'absence de \n à la fin du tableau signale cette coupure, ou une dernière ligne sans retour à la ligne.

  • n doit être la taille du tableau. sizeof ligne marche sur un tableau déclaré dans la fonction, pas sur un pointeur reçu en paramètre, qui ne mesure que 8 octets.

  • Après un scanf("%d", &age), le \n tapé derrière le nombre reste dans le tampon d'entrée, et le fgets suivant lit une ligne vide.

Exemple

fgets.c
#include <stdio.h>
int main(void){    char ligne[8];
    while (fgets(ligne, sizeof ligne, stdin) != NULL)        printf("[%s]\n", ligne);    return 0;}
Terminal
$ gcc -Wall -Wextra -g fgets.c -o fgets$ printf "Rabat\nCasablanca\n" | ./fgets[Rabat][Casabla][nca]

« Rabat » tient dans le tableau avec son \n, qui fait passer le crochet fermant à la ligne. « Casablanca » ne tient pas : le premier appel prend 7 caractères et le '\0', le second récupère le reste.

C

line_reader_repair

Écris read_next_line, qui renvoie avec read une ligne allouée par appel, retour à la ligne compris comme avec fgets, puis NULL en fin de fichier.

Ouvrir l'exercice

À toi d'écrire le code.