Get_next_line in C not stopping at the end of the file

I know there are many topics about this particular question but I can’t seems to find my exact problem. I’m trying to implement a get next line function with 42 norm.

I’ve been changing my function for 3 days without finding a proper solution for my get_next_line function to return NULL, once it has reached the end of the file (even if there are no new line), but still returning a string if “line” has something. I was trying to find a way that the loop stops when beeing re-called but nothing seems to work. Does someone has an idea ? Here is my code and thanks in advance:

    #include <unistd.h>
#include "get_next_line.h"
#include <stdio.h>

char    *ft_strdup(const char *str1)
{
    char    *str2;
    int     i;

    i = 0;
    str2 = (char *) malloc (ft_strlen(str1) + 1);
    if (str2 == NULL)
        return (NULL);
    while (str1[i])
    {
        str2[i] = str1[i];
        i++;
    }
    str2[i] = 0;
    return (str2);
}

char    *set_line(char *stash, char *line)
{
    int i;
    int j;

    i = ft_strchr_line(stash, '\n');
    j = ft_strlen(stash);
    if (i >= 0)
        line = ft_substr(stash, 0, i + 1);
    else
        line = ft_substr(stash, 0, j);
    return (line);
}

int ft_strchr_line(const char *line, int c)
{
    int i;

    i = 0;
    while (line && line[i])
    {
        if (line[i] == (char) c)
            return (i);
        i++;
    }
    if (!line || line[i] == 0)
        return (-2);
    return (-1);
}

char    *fill_line_buffer(int fd, char *stock, char *buffer)
{
    int i;
    int control;

    i = 1;
    control = 0;
    while (i > 0)
    {
        i = read(fd, buffer, BUFFER_SIZE);
        if (i == -1)
            return (NULL);
        buffer[i] = 0;
        stock = ft_strjoin(stock, buffer);
        control = ft_strchr_line(stock, '\n');
        if ((i == 0 && control == 0) || stock == NULL)
        {
            free(stock);
            return (NULL);
        }
        if (control > 0 || (i == 0 && control == -2))
            return (stock);
    }
    return (stock);
}

char    *get_next_line(int fd)
{
    char        buffer[BUFFER_SIZE + 1];
    static char *stock;
    char        *line;

    line = NULL;
    if (fd == -1)
        return (NULL);
    stock = fill_line_buffer(fd, stock, buffer);
    if (stock == NULL)
        return (NULL);
    line = set_line(stock, line);
    stock = set_stock(stock);
    return (line);
}
#include <fcntl.h>
#include <stdio.h>
int main(void)
{
    int fd;
    char    *line;
    fd = open("text_short.txt", O_RDONLY);
    while ((line = get_next_line(fd)) != NULL)
    {
        printf("%s", line);
        free(line);
    }
    return (0);
}
char    *set_stock(char *stock)
{
    int     i;
    int     j;
    char    *new_stock;

    i = ft_strchr_line(stock, '\n');
    j = ft_strlen(stock);
    if (i >= 0)
        new_stock = ft_substr(stock, i + 1, j);
    else
        return (stock);
    return (new_stock);
}

static int  s_len(char const *s, unsigned int start, size_t len)
{
    size_t  s_len;

    s_len = ft_strlen(s);
    if (start + len > s_len)
        len = s_len - start;
    return (len);
}

char    *ft_substr(char const *s, unsigned int start, size_t len)
{
    unsigned int        i;
    char                *str;

    i = 0;
    len = s_len(s, start, len);
    if (len < 0)
        return ((char *) s);
    if (start > (unsigned int) ft_strlen(s))
    {
        str = malloc(1);
        if (str == NULL)
            return (NULL);
        *str = 0;
        return (str);
    }
    str = malloc(len + 1);
    if (str == NULL)
        return (NULL);
    while (i < len)
    {
        str[i] = s[start + i];
        i++;
    }
    str[i] = 0;
    return (str);
}

char    *ft_strjoin(char *s1, char const *s2)
{
    int     i;
    int     j;
    char    *str3;

    i = 0;
    j = 0;
    str3 = (char *)malloc(ft_strlen(s1) + ft_strlen(s2) + 1);
    if (str3 == NULL)
        return (NULL);
    while (s1 && s1[i])
        str3[j++] = s1[i++];
    i = 0;
    while (s2 && s2[i])
        str3[j++] = s2[i++];
    str3[j] = 0;
    s1 = ft_strdup(str3);
    free(str3);
    if (s1 == NULL)
        return (NULL);
    return (s1);
}

int ft_strlen(const char *s)
{
    int i;

    i = 0;
    while (s && s[i])
        i++;
    return (i);
}

Added :the description of what we have to do :

  • List item

“Function name : get_next_line

  • List item
    Prototype : char *get_next_line(int fd);
  • List item

Turn in files : get_next_line.c,get_next_line_utils.c, get_next_line.h

  • List item

Parameters fd: The filedescriptor to read from

  • List item

Return value Read line: correct behavior
NULL:there is nothing else to read, or an error occurred

  • List item

External functs.read, malloc, free

  • List item

Description Write a function that returns a line read from a file descriptor • Repeated calls (e.g., using a loop) to
your get_next_line() function should let you read the text filepointed to by the file descriptor, one line at a time.Your functionshould return the line that was read. If there is nothing else to reador if an error occurred, it should return NULL. • Make sure that yourfunction works as expected both when reading a file and when reading from the standard input. • Please note that the returned line should include the terminating \n character, except if the end of file was reached and does not end with a \n character. You will compile your code as follows (a buffer size of 42 is used as an example): cc -Wall> -Wextra -Werror -D BUFFER_SIZE=42 .c

  • 1

    Have you tried to use a debugger to step through your code, line by line while monitoring variables and their values, to see what really happens?

    – 

  • And maybe document how you expect this to work?

    – 

  • “with 42 norm”??? What does that mean?

    – 

  • 2

    You vastly overcomplicate the situation. Read characters one by one in a loop. See \n? Return the string. See EOF? Return NULL (or whatever you want).

    – 

  • 2

    @Shawn I’ve always wondered where the ft_ prefix came from.

    – 

Leave a Comment