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
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?
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).@Shawn I’ve always wondered where the
ft_
prefix came from.Show 4 more comments