get_next_line 코드

get_next_line

  • header 파일
#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

좋은 웹페이지 즐겨찾기