get next lineコード


get_next_line

  • ヘッダファイル
  • #ifndef GET_NEXT_LINE_H
    # define GET_NEXT_LINE_H
    
    # include <stdlib.h>
    # include <unistd.h>
    
    # ifndef OPEN_MAX
    #  define OPEN_MAX 256
    # endif
    
    # ifndef BUFFER_SIZE
    #  define BUFFER_SIZE 128
    # endif
    
    # ifndef LINE_BUF_SIZE
    #  define LINE_BUF_SIZE 128
    # endif
    
    typedef struct s_buffer
    {
    	char	*buf;
    	size_t	pos;
    	size_t	size;
    }	t_buffer;
    
    typedef t_buffer	t_line_buffer;
    typedef t_buffer	t_read_buffer;
    
    char	*get_next_line(int fd);
    
    #endif
  • get_next_line.c
  • #include "get_next_line.h"
    
    void	*ft_memcpy(void	*dst, const void	*src, size_t	n);
    void	free_read_buffer(t_read_buffer *prb);
    
    static char	*realloc_line_buffer(t_line_buffer	*plb)
    {
    	char	*new_buf;
    	size_t	new_size;
    
    	new_size = plb->size + LINE_BUF_SIZE;
    	new_buf = malloc(sizeof(char) * (new_size + 1));
    	if (plb->buf != NULL)
    	{
    		if (new_buf != NULL)
    			ft_memcpy(new_buf, plb->buf, plb->size);
    		free(plb->buf);
    	}
    	plb->buf = new_buf;
    	plb->size = new_size;
    	return (new_buf);
    }
    
    static char	*alloc_read_buffer(t_read_buffer *prb)
    {
    	if (prb->buf == NULL)
    	{
    		prb->buf = malloc(sizeof(char) * BUFFER_SIZE);
    		if (prb->buf == NULL)
    			return (NULL);
    		prb->pos = 0;
    		prb->size = 0;
    	}
    	return (prb->buf);
    }
    
    static int	read_char(int fd, t_read_buffer *prb)
    {
    	if (prb->pos >= prb->size)
    	{
    		prb->size = read(fd, prb->buf, BUFFER_SIZE);
    		if (prb->size < 1)
    			return ('\0');
    		prb->pos = 0;
    	}
    	return (prb->buf[prb->pos++]);
    }
    
    static int	put_line_char(t_line_buffer *plb, char ch)
    {
    	if (plb->pos >= plb->size)
    	{
    		if (realloc_line_buffer(plb) == NULL)
    			return (0);
    	}
    	plb->buf[plb->pos++] = ch;
    	if (ch == '\n')
    		return (0);
    	return (1);
    }
    
    char	*get_next_line(int fd)
    {
    	int	ch;
    	t_line_buffer	lb;
    	static t_read_buffer	rb[OPEN_MAX] = {{NULL, 0, 0}};
    
    	if (fd < 0 || fd >= OPEN_MAX || BUFFER_SIZE <= 0)
    		return (NULL);
    	if (alloc_read_buffer(&rb[fd]) == NULL)
    		return (NULL);
    	lb.buf = NULL;
    	lb.pos = 0;
    	lb.size = 0;
    	while (1)
    	{
    		ch = read_char(fd, &rb[fd]);
    		if (ch == '\0')
    			break ;
    		if (put_line_char(&lb, ch) == 0)
    			break ;
    	}
    	if (lb.pos == 0)
    		free_read_buffer(&rb[fd]);
    	else
    		lb.buf[lb.pos] = '\0';
    	return (lb.buf);
    }
  • get_next_line_utils.c
  • #include "get_next_line.h"
    
    void	*ft_memcpy(void	*dst, const void	*src, size_t	n)
    {
    	unsigned char	*in_dst;
    	unsigned char	*in_src;
    
    	if (!dst && !src)
    		return (NULL);
    	in_dst = (unsigned char *) dst;
    	in_src = (unsigned char *) src;
    	while (n-- > 0)
    		*in_dst++ = *in_src++;
    	return (dst);
    }
    
    void	free_read_buffer(t_read_buffer *prb)
    {
    	if (prb->buf != NULL)
    	{
    		free(prb->buf);
    		prb->buf = NULL;
    	}
    }
  • main.c
  • #include "get_next_line.h"
    #include <stdio.h>
    #include <fcntl.h>
    
    int main()
    {
    	int fd;
    	int fd2;
    
    	fd = open("test.txt", O_RDONLY);
    	fd2 = open("test2.txt", O_RDONLY);
    	printf("buf=%s", get_next_line(fd));
    	printf("buf=%s", get_next_line(fd2));
    	printf("buf=%s", get_next_line(fd));
    
        return 0;
    }
  • compile
  • gcc -Wall -Wextra -Werror -D BUFFER_SIZE=42 <파일들>.c
  • tester
  • https://github.com/Tripouille/gnlTester.git