Well, i am trying to create a program that reads from a file descriptor piece by piece (defined as BUFFER_SIZE), until it finds a '\n' or the EOF. The problem its i am getting stuck in a infinite loop, which i try to address the cause without success, (you can notice the printf's all around the code). note: for this assignment i am only allowed to use a limited number of standard functions so to use realloc i have to implement my own, same with strlen and others. (assume that they are correct). ALLOWED FUNCTIONS: WRITE, READ, MALLOC AND FREE. There is the code:
void *ft_realloc(void *ptr, size_t oldsize, size_t size)
{
void *new;
size_t minsize;
if (size == 0)
{
free(ptr);
return (NULL);
}
if (ptr == NULL)
return (malloc(size));
new = malloc(size);
if (!new)
return (NULL);
minsize = size;
if (oldsize < size)
minsize = oldsize;
memcpy(new, ptr, minsize);
while (size - oldsize != 0)
((char *)new)[oldsize++] = '\0';
free(ptr);
return (new);
}
int find_newline_eof(char *buffer)
{
int i;
i = 0;
if (!buffer)
return (-1);
while (buffer[i])
{
if (buffer[i] == '\n')
return (i);
i++;
}
return (-1);
}
char *extract_line(char **buffer, int newline_pos)
{
char *line;
int remaining_len;
//in terms of params, to newline be -1, means that we reach EOF
without '\n'
if (!*buffer)
return (NULL);
if (newline_pos == -1)
newline_pos = ft_strlen(*buffer);
line = malloc(newline_pos + 1);
if (!line)
return (NULL);
memcpy(line, *buffer, newline_pos);
line[newline_pos] = '\0';
if ((*buffer)[newline_pos] == '\n')
newline_pos++;
printf("reached EXTRACT_LINE, line: (%s)\n", line);
return (NULL); // The function reaches HERE, the error is beyond.
remaining_len = ft_strlen(*buffer + newline_pos);
// memmove safer against overlapping than memcpy
memmove(*buffer, *buffer + newline_pos, remaining_len + 1);
*buffer = ft_realloc(*buffer, ft_strlen(*buffer), remaining_len + 1);
if (!*buffer)
{
free(line);
return (NULL);
}
return (line);
}
int read_newpiece(int fd, char **buffer)
{
int bytes_readed;
char current_buffer[BUFFER_SIZE + 1];
char *new_buffer;
bytes_readed = read(fd, current_buffer, BUFFER_SIZE);
if (bytes_readed <=0) //SAFE CHECKS
return (bytes_readed);
current_buffer[bytes_readed] = '\0';
//printf("entered here!\n");
//return (bytes_readed);
if (!*buffer)
{
*buffer = malloc(1);
if (!*buffer)
return (-1);
(*buffer)[0] = '\0'; // Initialize as an empty string
}
new_buffer = ft_realloc(*buffer, ft_strlen(*buffer),
ft_strlen(*buffer) + bytes_readed + 1);
if (!new_buffer)
return (-1);
*buffer = new_buffer;
strncat(*buffer, current_buffer, bytes_readed);
return (bytes_readed);
}
char *get_next_line(int fd)
{
static char *buffer = NULL;
char *line; //returned value
int newline_index; //position where we find the EOF or '\n';
if (fd < 0 || BUFFER_SIZE <= 0)
return (NULL);
if (!buffer)
{
buffer = malloc(1);
if (!buffer)
return (NULL);
buffer[0] = '\0';
}
newline_index = -1; //-1 (NOT FOUND)
while (newline_index == -1 && read_newpiece(fd, &buffer) > 0)
{
printf("buffer after read: /%s/\n", buffer);
newline_index = find_newline_eof(buffer);
printf("newline index: %d\n", newline_index);
//return (NULL);
}
if (newline_index == -1 && !buffer)
return (NULL);
line = extract_line(&buffer, newline_index);
printf("extracted line: ///%s///\n", line);
return (NULL);
}
int main(int ac, char **av)
{
int fd;
char *line;
if (ac < 2)
return (write(1, "Usage: ./a.out <filename>\n", 27));
fd = open(av[1], O_RDONLY);
if (fd <= -1) //SAFE CHECKS
return (write(1, "error opening file\n", 20));
while ((line = get_next_line(fd)) != NULL)
{
printf("%s\n", line);
free (line);
}
close (fd);
return (0);
}
the realloc take three params, the original buffer, the length of this buffer and the new desired size. It copies the entire buffer to a new one if the size > length, and copies (size) characters if the size if size < length. I appreciate any suggestion on any aspect of the code, but mainly to resolve the problem
i try to identify the issue step by step with aid of printf to check the value in some contexts
write(1, "error opening file\n", 20), instead of relying on counting bytes, use something likestatic const char msg1[] = "error opening file\n"; write( 1, msg1, sizeof( msg1 ) - 1 );Use multiple variable names likemsg1,msg2, etc so you can easily use have more than one message.find_newline_eof()do? How does it detect EOF? What happens if the input file doesn't end with newline?return (bytes_readed);inread_newpiece()ever executes. So it never copied intobuffer.static char *buffer = NULLis going to be trouble when you malloc it.