파일디스크립터를 받아와 해당 파일에서 개행으로 끝나는 한줄의 문장을 반환하는 함수
char *get_next_line(int fd)
{
char *readstr;
static char *backup[OPEN_MAX];
char *str;
int readsize;
int j;
j = 0;
if (BUFFER_SIZE <= 0 || fd < 0 || fd >= OPEN_MAX)
return (0);
readstr = malloc(sizeof(char) * (BUFFER_SIZE + 1));
if (!readstr)
return (0);
while (!ft_strchr(backup[fd], '\n'))
{
readsize = read(fd, readstr, BUFFER_SIZE);
if (readsize <= 0)
break ;
readstr[readsize] = '\0';
backup[fd] = ft_strjoin(backup[fd], readstr);
}
str = make_line(backup[fd], j);
backup[fd] = cut_line(backup[fd]);
return (str);
}
1. 받아온 fd가 음수인지, BUFFER_SIZE가 0이하 인지 확인
if (BUFFER_SIZE <= 0 || fd < 0 || fd >= OPEN_MAX) return (0);
- BUFFER_SIZE가 0 또는 음수라면 read함수에서 제대로 문자열을 불러올 수 없기때문에 종료
- fd가 음수인것은 정상적인 상황이 아니니 종료
- fd가 OPEN_MAX보다 크면 안되므로 종료
2. 반복문을 사용해 read함수로 BUFFER_SIZE만큼 문자열을 받아오고 정적변수에 저장, 또한 해당 문자열에 개행이 포함되어있다면 반복문 종료
while (!ft_strchr(backup[fd], '\n')) { readsize = read(fd, readstr, BUFFER_SIZE); if (readsize <= 0) break ; readstr[readsize] = '\0'; backup[fd] = ft_strjoin(backup[fd], readstr); }
- 문자열에서 특정 문자가 나온다면 해당 문자의 위치를 반환하는 ft_strchr 함수를 사용해 개행문자가 나온다면 반복문을 빠져나옴
- read함수를 사용해 BUFFER_SIZE만큼 문자열을 읽고 readstr에 저장해줌, 그리고 읽어온 문자열의 길이를 readsize에 저장해줌
- 만약 readsize가 0이라면 더이상 읽어올 문자열이 없는것이므로 반복문을 종료
- readstr의 끝에 문자열이 끝났음을 표시하는 '\0'을 넣어줌
- 정적변수에 들어있는 전에 읽었던 문자열과 이번에 읽었던 문자열을 합쳐줘야하므로 ft_strjoin을 사용해 두 문자열을 합쳐줌
3. 받아온 문자열을 사용해 개행문자가 나오거나 문자열이 종료될때 까지 한줄의 문자를 완성하고 반환시켜줌
str = make_line(backup[fd]); ...
char *make_line(char *backup, int j) { char *str; if (backup == NULL) return (NULL); if (backup[0] == '\0') return (NULL); while (backup[j] != '\n' && backup[j] != '\0') j++; if (backup[j] == '\n') str = malloc(sizeof(char) * (j + 2)); else str = malloc(sizeof(char) * (j + 1)); if (!str) return (0); j = 0; while (backup[j] != '\n' && backup[j] != '\0') { str[j] = backup[j]; j++; } if (backup[j] == '\n') str[j++] = '\n'; str[j] = '\0'; return (str); }
- backup이 NULL이라면 현재 정적변수에 아무것도 할당되지않은것이니 그대로 NULL을 반환
- backup[0] 이 '\0'인것은 현재 정적변수에 남아있는 문자열이 없는것이니 NULL을 반환
- 반복문을 사용해 문자열에 \n이나 \0이 나올때까지 인덱스값 증가
- \n로 끝났다면 \n과 \0두가지를 더 넣어줘야하므로 인덱스값 + 2만큼 str문자열에 저장공간을 할당
- \0으로 끝났다면 \0을 넣어줘야하므로 인덱스값 + 1만큼 str문자열에 저장공간을 할당
- 반복문을 사용해 \n 또는 \0이 나올때까지 정적변수에 저장된 문자열을 str로 복사해줌
- 문자열이 \n으로 끝났다면 str에도 \n을 넣어줌
- 문자열 한줄이 완성되었으므로 \0을 넣어주고 문자열을 반환
4. 문자열을 저장해둔 정적변수에서 방금 출력한 한줄만큼을 삭제한 새 문자열을 만들고 정적변수에 넣어줌
backup[fd] = cut_line(backup[fd]); ...
char *cut_line(char *backup) { int i; char *str; i = 0; if (backup == NULL) return (NULL); while (backup[i] != '\n' && backup[i] != '\0') i++; if (backup[i] == '\0') { free(backup); return (NULL); } if (backup[i] == '\n') i++; str = ft_strdup(&backup[i]); free(backup); return (str); }
- backup이 NULL이라면 현재 정적변수에 아무것도 할당되지않은것이니 그대로 NULL을 반환
- 반복문을 사용해 문자열에 \n이나 \0이 나올때까지 인덱스값 증가
- 만약 \0이 나왔다면 읽어온 파일이 끝난것이므로 free해주고 NULL 반환
- 만약 \n이 나왔다면 해당자리는 일단 건너야하므로 인덱스값을 1 증가
- 현재 위치부터 끝까지의 문자열을 새롭게 만들어주는 ft_strdup함수를 사용해 backup[i]부터 끝까지의 문자열을 새로 할당하여 str에 저장
- 기존에 사용하던 backup을 free해주고 새로 만든 str을 반환