when
- 23.06.05 월 20:00 ~ 04:20
- 23.06.06 화 12:20 ~ 17:00
- 23.06.09 금 20:00 ~ 02:00
- 23.06.12 일 17:00 ~ 24:00 (평가)
내용 | |
---|---|
프로토타입 | char *get_next_line(int fd) |
제출 파일 | get_next_line.c, get_next_line_utils.c, get_next_line.h |
Makefile | NAME, all, clean, fclean, re |
외부 함수 | malloc, free, read |
매개변수 | 읽어들일 파일의 descriptor (서술자) |
norm error 금지
segmetation fault, bus error, double free 금지
heap에 동적 할당된 메모리 해제 (메모리 누수 방지)
Makefile
보너스 제출
사용 금지
char *get_next_line(inf fd);
과제 구현
main으로 test
개행으로 끝나는 한 줄을 읽고, 반환하는 함수 (호출 할 때마다 함수는 한 번에 한 줄씩)
컴파일러 호출시 : -D BUFFER_SIZE=n 옵션 추가
읽은 라인의 문자열
반환 NULL
반환 #include <unistd.h>
size_t read(int fd, void *buf, size_t count);
fd : open 으로 열린 파일을 가리키는 파일 지정 번호
buf : 읽은 데이터를 저장할 공간
count : 읽을 데이터의 크기로 byte 단위
읽어온 바이트 수
반환 0
반환 : 0 (EOF) 파일을 끝까지 읽었으면, 다음번에는 더 이상 읽을 바이트가 없으므로 0을 반환-1
반환 : 실패시 -1을 반환📖 참고 📖 fgets vs read 차이점
- fgets : 첫번째 행만 읽어서 반환
- read : 버퍼의 크기만큼 읽어서 반환
read(fd, buf, buffsize)하면 데이터를 읽은 만큼 offset를 증가
파일 디스크립터 테이블(FD Table)에서 읽은 위치(offset)를 저장함
📖 참고 📖 버퍼 (buffer)
- 주기억장치와 주변 장치간 전송 속도 차이를 해결하기 위해 전송할 정보를 임시로 저장하는 고속 기억장치
- 파일을 읽을 때 사용할 임시 공간으로 버퍼 변수를 사용
- 특징 : 버퍼에는 용량이 한정되어 있기 때문에, 오버 플로우 현상이 발생할 수 있음
- 예시 : 표준 입출력함수 (scanf, printf 등)
void *malloc(size_t size)
함수 사용 : void *p = malloc(100);
힙(heap)
영역에 메모리를 할당 (Gbyte단위로 할당)#include <malloc.h>
free(p); // p가 가지고 있는 주소에 할당된 메모리를 해제함
할당된 메모리 해제
할당되지 않은 메모리를 해제하는 경우
할당된 메모리를 두 번 해제하는 경우
gcc -h *.c *.h
lldb a.out
r
or run
b 함수명/줄번호
n
or next
s
or step
p 변수명
or print 변수명
exit
#include "get_next_line.h"
char *ft_get_line(char *bp)
{
int i;
int n;
char *line;
i = 0;
if (*bp == '\0')
return (NULL);
n = 0;
while (*(bp + n) != '\n' && *(bp + n) != '\0')
n++;
line = (char *)malloc(sizeof(char) * n + 2);
if (!line)
{
free(bp);
return (NULL);
}
while (*(bp + i) != '\0' && *(bp + i) != '\n')
{
*(line + i) = *(bp + i);
i++;
}
if (*(bp + i) == '\n')
*(line + i++) = '\n';
*(line + i) = '\0';
return (line);
}
char *ft_get_backup(char *bp)
{
int n;
int len;
char *new;
n = 0;
while (*(bp + n) != '\n' && *(bp + n) != '\0')
n++;
if (*(bp + n) == '\0')
{
free(bp);
return (NULL);
}
len = ft_strlen(bp);
new = (char *)malloc(sizeof(char) * (len - n + 1));
if (!new)
{
free(bp);
return (NULL);
}
len = 0;
while (*(bp + ++n) != '\0')
*(new + len++) = *(bp + n);
*(new + len) = '\0';
free(bp);
return (new);
}
char *ft_read_file(int fd, char *backup, char *buf, int n)
{
char *prev;
while (n != 0)
{
n = read(fd, buf, BUFFER_SIZE);
if (n == -1)
{
free(backup);
return (NULL);
}
buf[n] = '\0';
prev = backup;
if (!prev)
prev = ft_strdup("");
backup = ft_strjoin(prev, buf);
if (!backup)
{
free(prev);
return (NULL);
}
free(prev);
if (ft_strchr(backup, '\n') != NULL)
break ;
}
return (backup);
}
char *get_next_line(int fd)
{
static char *backup;
char *line;
char *buf;
size_t n;
if (fd < 0 || BUFFER_SIZE <= 0)
return (NULL);
buf = (char *)malloc(sizeof(char) * BUFFER_SIZE + 1);
if (!buf)
return (NULL);
n = 1;
backup = ft_read_file(fd, backup, buf, n);
free(buf);
if (!backup)
return (NULL);
line = ft_get_line(backup);
backup = ft_get_backup(backup);
return (line);
}
#include "get_next_line.h"
size_t ft_strlen(const char *s)
{
size_t i;
i = 0;
if (!s)
return (0);
while (*(s + i) != '\0')
i++;
return (i);
}
char *ft_strjoin(char *s1, char *s2)
{
char *p;
size_t i;
size_t len;
if (!s1 && !s2)
return (NULL);
len = ft_strlen(s1) + ft_strlen(s2);
p = (char *)malloc(sizeof(char) * len + 1);
if (!p)
return (NULL);
i = 0;
len = 0;
while (*(s1 + i))
*(p + len++) = *(s1 + i++);
i = 0;
while (*(s2 + i))
*(p + len++) = *(s2 + i++);
*(p + len) = '\0';
return (p);
}
char *ft_strchr(char *s, int c)
{
size_t i;
i = 0;
while (*(s + i))
{
if (*(s + i) == c)
return (s);
i++;
}
return (NULL);
}
char *ft_strdup(const char *s)
{
char *p;
size_t i;
size_t len;
i = 0;
if (!s)
return (NULL);
len = ft_strlen(s);
p = (char *)malloc(sizeof(char) * (len + 1));
if (!p)
return (NULL);
while (*(s + i) != '\0')
{
*(p + i) = *(s + i);
i++;
}
*(p + i) = '\0';
return (p);
}
#ifndef GET_NEXT_LINE_H
# define GET_NEXT_LINE_H
# include <unistd.h>
# include <stdlib.h>
# ifndef BUFFER_SIZE
# define BUFFER_SIZE 42
# endif
size_t ft_strlen(const char *s);
char *ft_strjoin(char *s1, char *s2);
char *ft_strchr(char *s, int c);
char *ft_strdup(const char *s);
char *get_next_line(int fd);
char *ft_read_file(int fd, char *backup, char *buf, int n);
char *ft_get_line(char *bp);
char *ft_get_backup(char *bp);
#endif
#include <fcntl.h>
#include <stdio.h>
int main(void)
{
int fd;
char *line;
fd = 0;
fd = open("./test.txt", O_RDONLY);
while ((line = get_next_line(fd)) != NULL)
{
printf("%s", line);
free(line);
}
if (line == NULL)
printf("%s\n", line);
close(fd);
return (0);
}
📖 참고 📖 OPEN_MAX vs Linked List