get_next_line
get_next_lineest une fonction utilitaire en C qui lit une ligne à la fois depuis un descripteur de fichier (fd) et la retourne sous forme de chaîne allouée dynamiquement.
L’objectif du projet est double :
- Comprendre comment construire une lecture streaming (sans charger tout le fichier en mémoire).
- Maîtriser un concept clé en C : les variables statiques, indispensables pour conserver l’état entre deux appels.
Principe
À chaque appel, get_next_line(fd):
1. Lit depuis fd par blocs de taille BUFFER_SIZE.
2. Accumule les données jusqu’à trouver un \n ou atteindre la fin du flux.
3. Retourne la prochaine ligne :
- la ligne inclut le \n si la ligne en contient un,
- sauf en fin de fichier si le dernier morceau n’est pas terminé par \n.
Si aucune ligne n’est disponible (EOF) ou en cas d’erreur, la fonction retourne NULL.
Points importants
-
Des appels successifs permettent de lire l’intégralité d’un fichier/flux ligne par ligne.
-
La fonction doit fonctionner aussi bien sur un fichier que sur l’entrée standard.
-
La lecture doit être minimale : dès qu’un \n est rencontré, on retourne la ligne correspondante (on ne lit pas le fichier entier).
Contraintes respectées
-
Fonctions autorisées : read, malloc, free
-
Compilation avec la macro : -D BUFFER_SIZE=n (valeur testée avec plusieurs tailles)
-
Interdits : libft, lseek(), variables globales
Ce que ça m’a apporté
Ce projet m’a appris à écrire une fonction fiable sur un flux de données : gestion d’un buffer résiduel entre appels (via static), découpage propre "ligne retournée" / "reste à conserver", et attention aux cas limites (buffer très petit, très grand, fichiers sans \n, stdin, etc.).
Bonus
Version avec une seule variable statique.
Gestion de plusieurs fd en parallèle : lire fd=3, puis 4, puis 5, puis revenir à 3 sans perdre l’état de chacun.
Objectif
Implémenter get_next_line(int fd) : une fonction qui retourne la prochaine ligne lue depuis un file descriptor, à chaque appel.
Règles de retour
- La ligne retournée est une chaîne allouée (à
free()côté appelant). - La ligne inclut le
\nsi la ligne en contient un. - Si la fin de fichier est atteinte et qu’il reste des caractères sans
\n, on retourne cette dernière ligne. - Si EOF sans reste ou en cas d’erreur :
NULL.
Contraintes techniques
- Lecture par blocs via
read()avec une tailleBUFFER_SIZE. - Compilation avec :
-D BUFFER_SIZE=n(testée avec plusieurs valeurs). - Interdits selon sujet : pas de libft, pas de variables globales, pas de
lseek(). - Fonctions autorisées (classique) :
read,malloc,free.
Bonus
- Gestion de plusieurs fd sans perdre l’état de chacun.
- Variante imposant une seule variable statique (selon consignes).
Build
Exemple de compilation :
cc -Wall -Wextra -Werror -D BUFFER_SIZE=42 \
get_next_line.c get_next_line_utils.c \
main.c -o gnl
Exemple minimal
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.hn>
char *get_next_line(int fd);
int main(void)
{
int fd = open("file.txt", O_RDONLY);
char *line;
if (fd < 0)
return (1);
while ((line = get_next_line(fd)) != NULL)
{
printf("%s", line);
free(line);
}
close(fd);
return (0);
}
Notes importantes
- Toujours
free()chaque ligne. -
Tester avec :
-
fichier vide
- fichier sans
\n BUFFER_SIZE=1- très gros fichiers
stdin(fd = 0)
Idée centrale
Conserver un reste (stash) entre deux appels pour ne pas perdre les caractères après un \n.
Flux logique (mandatory)
- stash (statique) contient les données non consommées.
- Lire avec
read(fd, buffer, BUFFER_SIZE)tant que :
- aucun
\ndansstashet -
read()renvoie > 0
3. Dès qu’un\nest présent (ou EOF), construire : -
line= partie destashjusqu’au\ninclus (ou fin) stash= reste après la ligne (ouNULL)
4. Retournerline.
Découpage conseillé
read_to_stash(fd, stash): boucle de lecture jusqu’à trouver\nou EOF.extract_line(stash): crée la ligne à retourner.trim_stash(stash): garde uniquement ce qui reste après la ligne.utils(interdiction libft) :ft_strlen,ft_strchr,ft_strjoin,ft_substr(ou équivalents maison).
Gestion des erreurs
- Si
read()retourne-1: cleanup +NULL. - Si
mallocéchoue : cleanup +NULL.
Bonus multi-fd (si fait)
- Utiliser un
static char *stash[OPEN_MAX](ou structure équivalente) pour stocker un stash par fd. - Même algorithme, mais indexé sur
fd.
Pourquoi c’est intéressant
Ce projet combine I/O bas niveau, gestion mémoire, et état persistant (via static) — le tout avec des cas limites très concrets (fichiers sans \n, petites tailles de buffer, stdin, multi-fd).