01.Circle [Get_Next_Line]

HYEONGWOO IM·2022년 10월 28일
0

42seoul

목록 보기
1/2

(1) 구현순서

  1. fd 및 BUFFER_SIZE 예외처리
  2. 읽은 문자열을 저장할 문자열 malloc (BUFFER_SIZE 크기)
  3. file read (BUFFER_SIZE 크기)
  4. '\n'을 만나기 전 까지 read와 join을 반복.
  5. 리턴할 문자열과 ('\n' 전 까지) 남길 문자열을 정적 변수에 구분

(2) 알아야할 점

read (int, void *, size_t)

read 함수는 열려있는 파일을 읽어주는? 함수로서 int는 파일 디스크립트 fd를 주어야 하며, void *는 리턴받을 주소, size_t는 읽을 크기를 넣어줘야 한다.
read에 성공할 시 읽은 크기를 반환하고 실패 시 -1을 반환한다.

static 자료형 변수명 (정적변수)

static는 초기화를 따로 하지 않아도 프로그램이 시작할 때 할당됨과 동시에 0으로 자동으로 초기화 되며, 함수가 종료되어도 프로그램이 종료되지 않았다면 초기화되지 않음.

(3) 로직

char	*get_next_line(int fd)
{
	char		*line;
	static char	*str;

	str = ft_read_to_left_str(fd, str);
	line = ft_get_line(str);
	str = ft_backup_str(str);
	return (line);
}

변수 선언 및 전체 흐름 제어.
str <- read한 문자열 저장
line <- '\n' 기준으로 왼쪽 문자열 저장
str <- '\n' 기준 오른쪽 문자열 저장

'\n' 기준으로 왼쪽과 오른쪽으로 나뉘는 이유는 '\n'의 위치가 read한 문자열의 끝에만 존재하는게 아닌 중간과 시작 등 다양한 위치에 존재하고 get_next_line에서는 buffer_size만큼 read하기 때문에 '\n'이후에도 문자열이 존재할 확률이 매우 크기 때문.

char	*ft_read_to_left_str(int fd, char *str)
{
	char	*buff;
	int		rd_bytes;

	buff = malloc(((size_t)BUFFER_SIZE + 1) * sizeof(char));
	rd_bytes = BUFFER_SIZE;
	while (!ft_strchr(str, '\n') && rd_bytes == BUFFER_SIZE)
	{
		rd_bytes = read(fd, buff, BUFFER_SIZE);
		if (rd_bytes == -1)

		if (rd_bytes == 0)

		buff[rd_bytes] = '\0';
		str = ft_strjoin(str, buff);
	}
	return (str);
}

while 문의 조건이 인자로 받은 str에 '\n'이 없을 때 이기 때문에 이전의 read에서 '\n'이 있었다면 while 문이 돌지 않는다.
while 문이 끝나면 문자열 str에는 '\n'이 들어가 있기 때문에 바로 return 해주고 함수를 종료한다.

char	*ft_get_line(char *str)
{
	int		i;
	char	*line;

	i = 0;
	if (!str[i])
		return (NULL);
	while (str[i] && str[i] != '\n')
		i++;
	line = (char *)malloc(sizeof(char) * (i + 2));
	if (!line)
		return (NULL);
	i = 0;
	while (str[i] && str[i] != '\n')
	{
		line[i] = str[i];
		i++;
	}
	if (str[i] == '\n')
	{
		line[i] = str[i];
		i++;
	}
	line[i] = '\0';
	return (line);
}

'\n' 이전의 문자열을 만들어서 return 해야하므로 while 문을 통해 malloc size를 확인 한 후 '\n'과 '\0'을 포함하기 위해 size 에 + 2를 해준다.

char	*ft_backup_str(char *str)
{
	int		i;
	int		j;
	char	*backup;

	i = 0;
	while (str[i] && str[i] != '\n')
		i++;
	if (!str[i])
	{
		free(str);
		return (NULL);
	}
	backup = (char *)malloc(sizeof(char) * (ft_strlen(str) - i + 1));
	if (!backup)
		return (NULL);
	i++;
	j = 0;
	while (str[i])
		backup[j++] = str[i++];
	backup[j] = '\0';
	free(str);
	return (backup);
}

이제 '\n'다음의 문자열을 return 해야 하므로
전체 길이 - '\n'의 길이 + 1('\0') size를 malloc 해준다.
그리고 복사~!

Bonus Part

보너스 파트에 대해서는 배열로 하냐, 연결리스트로 하냐 의견이 많은데 0circle 과제 libft를 사용하지 않는것으로 보아 배열이 맞지 않나 하는 생각이 든다.
push_swap을 연결리스트를 통해 구현하여서 그런지 이제는 연결리스트로 하는것도 어렵지 않겠다 라는 생각이 든다.

0개의 댓글