A low-level C function that reads a file line by line, demonstrating efficient buffer handling, file descriptor management, and dynamic memory control.
get_next_line is a core project in the 42 curriculum, designed to teach how to interact with the operating system at a low level using file descriptors and dynamic memory management.
The goal is to implement a function capable of reading a file one line at a time, regardless of the file size or the buffer size.
- Built with: C
- Focus: Reading from file descriptors line by line using buffers, static variables, and dynamic memory.
- What I learned: File handling, memory management, buffer logic, static storage, and edge-case handling.
Implement the function:
char *get_next_line(int fd);This function reads from a file descriptor and returns the next line of the file each time it is called.
The function must:
-
Read from a file descriptor
-
Return one line per function call
-
Include the newline character \n when present
-
Work with any BUFFER_SIZE
-
Return NULL when there is nothing left to read
-
Avoid memory leaks
-
Handle files of any size
The algorithm works in four main stages:
read() → buffer → stash → extract line → return line
1️⃣ Read from the file descriptor using read()
2️⃣ Store the read data in a temporary buffer
3️⃣ Append that data to a static stash
4️⃣ Extract the first complete line
5️⃣ Return the line
6️⃣ Keep the remaining data for the next call
The key to get_next_line is the static variable.
static char *stash;A static variable:
-
persists between function calls
-
stores leftover data after a line is returned
File content:
Hello world\nHow are you\n42After the first read:
stash = "Hello world\nHow are you\n42"Returned line:
Hello world\nRemaining stash:
How are you\n42FILE
│
▼
read(fd, buffer, BUFFER_SIZE)
│
▼
BUFFER
│
▼
append to STASH
│
▼
Is newline found?
│
├─ YES → extract line
│ update stash
│ return line
│
└─ NO → read more
get_next_line/
│
├── get_next_line.c
├── get_next_line.h
│
├── get_next_line_bonus.c
├── get_next_line_bonus.h
│
└── README.md
Files:
-
get_next_line.c
-
get_next_line.h
Handles reading from a single file descriptor.
Files:
-
get_next_line_bonus.c
-
get_next_line_bonus.h
Adds support for multiple file descriptors simultaneously.
Implementation uses an array of stashes:
static char *stash[FD_MAX];This allows the function to maintain a separate buffer for each file descriptor.
Typical helper functions include:
ft_strlen
Calculate string length.
ft_strjoin
Concatenate strings dynamically.
ft_strchr
Locate newline characters.
ft_substr
Extract a portion of a string.
These utilities allow safe manipulation of dynamically allocated strings.
#include <fcntl.h>
#include <stdio.h>
int main(void)
{
int fd = open("file.txt", O_RDONLY);
char *line;
while ((line = get_next_line(fd)))
{
printf("%s", line);
free(line);
}
}Hello
World
42
NetworkHello
World
42
Network
Each line is returned separately with every call to get_next_line.
Compile the mandatory part:
cc -Wall -Wextra -Werror get_next_line.cCompile the bonus part:
cc -Wall -Wextra -Werror get_next_line_bonus.cThe implementation correctly handles:
-
Very large files
-
Files without newline at the end
-
Multiple file descriptors (bonus)
-
BUFFER_SIZE values of any size
-
Empty files
-
Files containing only newline characters
This project strengthens understanding of:
-
System Programming
-
file descriptors
-
read() system call
-
Memory Management
-
malloc
-
free
-
avoiding memory leaks
-
Algorithms
-
incremental reading
-
efficient string manipulation
-
state preservation across calls
-
Debugging
-
segmentation faults
-
buffer overflows
-
memory leaks
-
static variables
-
dynamic memory allocation
-
file descriptor management
-
buffered input handling
-
modular C design
GitHub:
https://github.com/wkratos77⭐ If you found this project interesting, feel free to explore the implementation.