Get Next Line
42 Abu Dhabi

Get Next Line

Line-by-Line File Reading Function

2 weeks
Individual Project
CFile I/OMemory ManagementStatic Variables

A function that reads a file line by line, handling multiple file descriptors simultaneously while managing memory efficiently and dealing with various buffer sizes.

Key Features

Line-by-Line Reading

Efficiently reads files one line at a time, returning each line including the newline character when present.

Multiple File Descriptors

Handles multiple file descriptors simultaneously, maintaining separate read states for each file.

Memory Optimization

Implements efficient memory management with minimal allocations and proper cleanup to prevent memory leaks.

Configurable Buffer

Works with different buffer sizes defined at compile time, adapting to various reading scenarios.

Development Journey

Phase 1

Basic File Reading

Implemented basic file reading functionality with buffer management and initial line extraction logic.

Phase 2

Memory Management

Developed dynamic memory allocation strategies and implemented proper cleanup mechanisms to prevent memory leaks.

Phase 3

Multiple File Descriptors

Extended functionality to handle multiple file descriptors simultaneously with static variable management.

Challenges & Solutions

Memory Management

Problem:

Managing dynamic memory allocation while preventing leaks and handling edge cases with multiple file operations.

Solution:

Implemented careful memory tracking with proper cleanup routines and edge case handling for all allocation scenarios.

Multiple File Descriptors

Problem:

Maintaining separate state for multiple files being read simultaneously without data corruption.

Solution:

Used static variables and linked list structures to track individual file reading states with proper isolation.

Buffer Size Optimization

Problem:

Handling different buffer sizes efficiently while maintaining consistent performance across various file types.

Solution:

Developed adaptive buffering strategy that works efficiently with compile-time buffer size configuration.

get_next_line.c
c
// Main get_next_line function
char *get_next_line(int fd)
{
    static char *buffer;
    char        *line;
    char        *temp;
    int         bytes_read;

    if (fd < 0 || BUFFER_SIZE <= 0)
        return (NULL);

    bytes_read = 1;
    while (!ft_strchr(buffer, '\n') && bytes_read != 0)
    {
        temp = malloc(BUFFER_SIZE + 1);
        if (!temp)
            return (NULL);
        bytes_read = read(fd, temp, BUFFER_SIZE);
        if (bytes_read == -1)
        {
            free(temp);
            return (NULL);
        }
        temp[bytes_read] = '\0';
        buffer = ft_strjoin(buffer, temp);
        free(temp);
    }
    
    line = extract_line(buffer);
    buffer = update_buffer(buffer);
    
    return (line);
}

// Extract line from buffer
char *extract_line(char *buffer)
{
    char    *line;
    int     i;

    if (!buffer)
        return (NULL);
    
    i = 0;
    while (buffer[i] && buffer[i] != '\n')
        i++;
    
    line = malloc(i + 2);
    if (!line)
        return (NULL);
        
    ft_strncpy(line, buffer, i + 1);
    line[i + 1] = '\0';
    
    return (line);
}