This project has been created as part of the 42 curriculum by someyer
Description
In this project I needed to create a function with following signature:
char *get_next_line(int fd);
This function should do the following:
- Repeated calls (e.g., using a loop) to my
get_next_line()function should let
me read the text file pointed to by the file descriptor, one line at a time. - My function should return the line that was read. If there is nothing left to read or if an error occurs, it should return
NULL.

Instructions
In project’s folder you will find get_next_line_utils.c, get_next_line.c, get_next_line.h and README.md files.
Browse my files, make sure, that name of the files are correct and check norminette for my .c files:
norminette get_next_line.c get_next_line_utils.c
Use my function
You can just follow evaluation guidelines and check it for yourself, ignoring this stuff below. Nevertheless, I prepared some easy tests and files for you.
At first, we need to create a test files. I’ll put them in separate folder:
mkdir -p files
printf "HellonWorldnFoon" > files/normal.txt
printf "Last line no newline" > files/no_newline.txt
touch files/empty.txt
printf "n" > files/single_newline.txt
python3 -c "print('A' * 2001)" > files/long_line.txt
Create a new .c file for testing, e.g. name it: main.c
You can use this code to ensure, that everything works, this is not the code I wrote by my hand, but from AI, but I think it’s simple enough and has everything, that’s needed:
#include "get_next_line.h"
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
static void test_file(const char *path)
{
int fd;
char *line;
printf("n--- %s ---n", path);
fd = open(path, O_RDONLY);
if (fd < 0)
{
printf("Error opening file.n");
return;
}
while ((line = get_next_line(fd)))
{
printf("%s", line);
free(line);
}
close(fd);
}
int main(void)
{
char *line;
test_file("files/normal.txt");
test_file("files/no_newline.txt");
test_file("files/empty.txt");
test_file("files/single_newline.txt");
test_file("files/long_line.txt");
printf("n--- invalid fd ---n");
line = get_next_line(-1);
if (!line)
printf("NULLn");
free(line);
printf("n--- stdin (Ctrl+D to stop) ---n");
while ((line = get_next_line(0)))
{
printf("%s", line);
free(line);
}
return (0);
}
You can play around, I think result should be fine.
Test this function
Let’s check my function.
When the implementation was ready I used Tripouille tester to check if I haven’t forgotten to check anything.
You can download the tester in my project’s folder. Go to the tester’s folder and run:
make m
You should see something like this:

- Note: I know, that there is a timeout using small
BUFFER_SIZE = 1on the big line. I checked with other 42 students, who had similar approach to imlement this function, and Moulinette passed them.
It happens, because I useft_strjoinon every single byte to read that very long line, so I have a lot of join operations, which leads to a timeout on this tester.
Function logic
I used this approach, because it’s quite simple in its logic, and also I had a lot of peers, who had similar approach. As we already know, using ft_strjoin is quite a downside, when we had our tests, but overall this function just works.
Let’s look on our core function:
char *get_next_line(int fd)
{
static char *leftover;
char *line;
if (fd < 0 || BUFFER_SIZE <= 0)
return (NULL);
if (!leftover)
leftover = ft_strdup("");
leftover = read_to_leftover(fd, leftover);
if (!leftover || !*leftover)
{
free(leftover);
return (leftover = NULL);
}
line = extract_line(leftover);
leftover = update_leftover(leftover);
return (line);
}
This function doesn’t do the heavy lifting itself, instead, it coordinates the helpers to manage the static variable safely.
We use a static variable called leftover because it stays in memory even after the function finishes, allowing us to "remember" what we read but didn’t return yet.
I have a helper function read_to_leftover(fd, leftover), which reads data from file to my static variable. I’m reading in chunks. When I find a new line, or there’s nothing to read, reading stops.
These chunks are added to my leftover using ft_strjoin function from libft project.
char *read_to_leftover(int fd, char *leftover)
{
char *buffer;
int bytes_read;
char *tmp;
buffer = malloc(BUFFER_SIZE + 1);
if (!buffer)
return (NULL);
bytes_read = 1;
while (!ft_strchr(leftover, 'n') && bytes_read > 0)
{
bytes_read = read(fd, buffer, BUFFER_SIZE);
if (bytes_read == -1)
{
free(buffer);
free(leftover);
return (NULL);
}
buffer[bytes_read] = ' ';
tmp = leftover;
leftover = ft_strjoin(leftover, buffer);
free(tmp);
}
free(buffer);
return (leftover);
}
Now, if you return to my core function, you can see, that after I read data to my leftover, I extracted just one line, which will be returned. I also need to update my leftover, so it starts after ‘n’, giving us starting point for the next line.
char *update_leftover(char *leftover)
{
char *next_line;
char *new_leftover;
next_line = ft_strchr(leftover, 'n');
if (!next_line)
{
free(leftover);
return (NULL);
}
new_leftover = ft_strdup(next_line + 1);
free(leftover);
return (new_leftover);
}
Now if we call the function next time, it should give you next line.
Resources
- My peers in 42 Prague & evaluations.
- Tripouille’s get_next_line tester: link
- I was quite stuck, after I used the tester for the first time. Gemini & Claude helped me to find, that I have name BUFF_SIZE instead of BUFFER_SIZE, which lead to fail on few of my cases. It took me about 2 hours to recognize that, yes.

Leave a Reply