Search
๐Ÿ“Ÿ

getnextline

Created
2022/01/13 13:26
Updated
2022/01/13 13:32
Tags
Circle 01
File Descriptor
Buffer
Author
Created
Updated
mcha(Min-jae Cha)
2022. 01. 13
2022. 01. 13

Subtitle

Reading a line on a fd is way too tedious

Version

10

Specification

Function name
get_next_line
Prototype
char *get_next_line(int fd);
Turn in files
get_next_line.c, get_next_line_utils.c, get_next_line.h
Parameters
File descriptor to read from
Return value
Read line: correct behavior NULL: nothing else to read or an error occurred
External functs.
read, malloc, free
Description
Write a function which returns a line read from a file descriptor

ย Before start

๋ณธ ๊ณผ์ œ์˜ ๋ชฉ์ ์€ ๊ณผ์ œ ๋ช… ๊ทธ๋Œ€๋กœ ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ๋กœ๋ถ€ํ„ฐ ์ฝํ˜€์ง„, ๊ฐœํ–‰์œผ๋กœ ๋๋‚˜๋Š” ํ•œ ์ค„์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ณผ์ œ์ž…๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž ๋˜๋Š” ๊ธฐ๊ณ„ ์ฑ„์ ์€ ์˜คํ”ˆ ํ•œ ํŒŒ์ผ์ธ fd๋ฅผ ํ•œ ๋ฒˆ๋งŒ ์ฝ์„ ์ˆ˜ ์žˆ๊ณ  ์—ฌ๋Ÿฌ ๋ฒˆ ์—ด๋žŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
About fd(File Descriptor)
์˜ˆ๋ฅผ ๋“ค์–ด ์•„๋ž˜์™€ ๊ฐ™์€ ํ…์ŠคํŠธ ํŒŒ์ผ์ด ์žˆ๋‹ค๊ณ  ์ƒ๊ฐ์„ ํ•ด ๋ด…์‹œ๋‹ค.
test.txt Hello My name is minjae How are you?
๋งŒ์•ฝ ์‚ฌ์šฉ์ž๊ฐ€ ํ•œ ๋ฒˆ๋งŒ fd๋ฅผ ์—ด๋žŒ ํ•˜์˜€๋‹ค๋ฉด ๊ฒฐ๊ณผ ๊ฐ’์€ "Hello" ์ผ ๊ฒƒ์ด๊ณ , fd๋ฅผ ๊ณ„์† ์—ด๋žŒ ํ•œ๋‹ค๋ฉด ๊ฒฐ๊ณผ๋Š” ์•„๋ž˜์™€ ๊ฐ™์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
Result example 1๋ฒˆ์งธ read "Hello" 2๋ฒˆ์งธ read "My name is minjae" 3๋ฒˆ์งธ read "How are you?" 4๋ฒˆ์งธ read NULL
๊ฒฐ๊ณผ์ ์œผ๋กœ ์ด ๊ณผ์ œ๋Š” ๋” ์ด์ƒ ์ฝ์„ ๊ฒƒ์ด ์—†๊ฑฐ๋‚˜ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒ ํ–ˆ์„ ๊ฒฝ์šฐ NULL์„ ๋ฐ˜ํ™˜ํ•ด ์ˆ˜ํ–‰์ด ๋๋‚จ์„ ์•Œ๋ฆฐ๋‹ค.

ย Respected value

1.
String โ†’ ํ•œ ์ค„์ด ์ œ๋Œ€๋กœ ์ฝํ˜”์„ ๊ฒฝ์šฐ
ํ•œ ์ค„์˜ ๋งˆ์ง€๋ง‰์— ๊ฐœํ–‰ ๋ฌธ์ž('\n')๊ฐ€ ์žˆ๊ฑฐ๋‚˜, EOF๋กœ ๋งˆ๋ฌด๋ฆฌ ๋˜์—ˆ์„ ๋•Œ.
์˜ˆ์‹œ
2.
NULL โ†’ ์ฝ์„ ๋ผ์ธ์ด ๋” ์ด์ƒ ์—†๊ฑฐ๋‚˜ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ์‹œ
โ†’ ๋นˆ ํŒŒ์ผ์ธ ๊ฒฝ์šฐ
์˜ˆ์‹œ
โ†’ ์œ ํšจํ•˜์ง€ ์•Š์€ fd(file descriptor)์ผ ๊ฒฝ์šฐ
a.
์กด์žฌํ•˜์ง€ ์•Š๋Š” fd invalid fd
์˜ˆ์‹œ
b.
์—ด ์ˆ˜ ์žˆ๋Š” ์ตœ๋Œ€ ํŒŒ์ผ ์ˆ˜๋ณด๋‹ค ๋†’์€ fd์ผ ๊ฒฝ์šฐ OPEN_MAX < fd
์˜ˆ์‹œ
โ†’ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น ์—๋Ÿฌ

ย How to do this?

์ฃผ์–ด์ง„ ํŒŒ์ผ์˜ ๋‚ด์šฉ (start) Hello('\n') (end of file)
โ†’ ์ฃผ์–ด์ง„ BUFFER_SIZE๋งŒํผ ํŒŒ์ผ์˜ ๋‚ด์šฉ์„ ์ฝ๊ธฐ (-D BUFFER_SIZE=<number>)
์˜ˆ์‹œ
โ†’ ๋ฐ›์•„์˜จ ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ๋ฅผ index๋กœ ์‚ฌ์šฉํ•˜์—ฌ ๋ฌธ์ž์—ด ์ด์–ด ๋ถ™์ด๊ธฐ
์˜ˆ์‹œ
ย BREAK POINT
1.
๋” ์ด์ƒ ์ฝ์„ ๋ฌธ์ž๊ฐ€ ์—†์„ ๋•Œ
โ†’ ์ž„์‹œ ๋ณ€์ˆ˜์ธ 'buf'์˜ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ•ด์ œ(free) ํ›„ ์ด์–ด ๋ถ™์ธ ptr ๋ฐ˜ํ™˜

ย CODE

ย char *get_next_line(int fd)

๋ณธ ๊ณผ์ œ์˜ ๋„์ž…๋ถ€์ด์ž ๋กœ์ง์„ ์ฒ˜๋ฆฌํ•˜๋Š” ํ•ต์‹ฌ ๋ถ€๋ถ„
๋ฐ˜ํ™˜ ํ˜•ํƒœ
char * (๋ฌธ์ž์—ด ๋˜๋Š” NULL)
ํŒŒ๋ผ๋ฏธํ„ฐ
fd โ†’ ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ
char *get_next_line(int fd) { // file descriptor์— ๋”ฐ๋ผ ๋ฌธ์ž์—ด์ด ๋“ค์–ด๊ฐˆ ๊ณต๊ฐ„ ์ƒ์„ฑ static char *ptr[10240]; // ๋ฐ˜ํ™˜ํ•  ๋ฌธ์ž์—ด์„ ๋‹ด์„ ๋ฐฐ์—ด char *line; // fd, BUFFER_SIZE ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ if (fd < 0 || BUFFER_SIZE < 1) return (NULL); // ํ•ด๋‹นํ•˜๋Š” ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ์˜ ๋‚ด์šฉ์„ ์ด์–ด๋ถ™์ž„ ptr[fd] = read_line(ptr[fd], fd); // ptr ๋„ ๊ฐ€๋“œ if (!ptr[fd]) return (NULL); // ๊ฐœํ–‰ ๋ฌธ์ž ๋˜๋Š” NULL๋ฌธ์ž๋กœ ์Šคํ”Œ๋ฆฟ line = do_split(ptr[fd]); // ์ž˜๋ผ์ง„ ๋ฌธ์ž์—ด ๋‹ค์Œ ์ฃผ์†Œ๋กœ ptr[fd] ์ด๋™ ptr[fd] = do_move(ptr[fd]); // ์ž˜๋ผ์ง„ ๋ฌธ์ž์—ด ๋ฐ˜ํ™˜ return (line); }
C
๋ณต์‚ฌ

ย static char *read_line(char *ptr, int fd)

fd์— ์žˆ๋Š” ๋‚ด์šฉ์„ ์ฝ์–ด์˜ค๋Š” ํ•จ์ˆ˜
๋ฐ˜ํ™˜ ํ˜•ํƒœ
char * (๋ฌธ์ž์—ด ๋˜๋Š” NULL)
ํŒŒ๋ผ๋ฏธํ„ฐ
char *ptr โ†’ ํ•ฉ์ณ์งˆ ๋ฌธ์ž์—ด int fd โ†’ ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ
static char *read_line(char *ptr, int fd) { // BUFFER_SIZE๋งŒํผ ์ฝ์€ ๋ฌธ์ž(๋ฌธ์ž์—ด)๊ฐ€ ๋“ค์–ด๊ฐˆ ์ž„์‹œ ๋ฐฐ์—ด char *buf; // ์ฝ์€ ๋ฌธ์ž ๊ฐœ์ˆ˜ int r_size; // BUFFER_SIZE + 1๋งŒํผ ๋™์ ํ• ๋‹น buf = (char *)malloc(sizeof(char) * (BUFFER_SIZE + 1)); // NULL ๊ฐ€๋“œ if (!buf) return (NULL); // ์ฝ์€ ๋ฌธ์ž ๊ฐœ์ˆ˜๋ฅผ 1๋กœ ์ดˆ๊ธฐํ™” r_size = 1; // ์ฝ์€ ๋ฌธ์ž ๊ฐœ์ˆ˜๊ฐ€ ์žˆ๊ณ  ๊ฐœํ–‰ ๋ฌธ์ž๊ฐ€ ์—†์„ ๋•Œ๊นŒ์ง€ ๋ฐ˜๋ณต while (r_size > 0 && nl_index(ptr, '\n') == -1) { // buf์— BUFFER_SIZE๋งŒํผ ์ฝ์–ด์˜ค๊ธฐ r_size = read(fd, buf, BUFFER_SIZE); // ๋งŒ์•ฝ ์ฝ์€ ๋ฌธ์ž๊ฐ€ ์—†๋‹ค๋ฉด break if (r_size == 0) break ; // ๋งŒ์•ฝ invalid fd ๋˜๋Š” ์˜ค๋ฅ˜ ๋ฐœ์ƒ ์‹œ if (r_size == -1) { // buf ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ ํ›„ NULL ๋ฐ˜ํ™˜ free(buf); return (NULL); } // ์ฝ์€ ๋ฌธ์ž๊ฐ€ ์žˆ๋‹ค๋ฉด ptr์— buf join buf[r_size] = '\0'; ptr = ft_strjoin(ptr, buf); } // buf free free(buf); // ptr ๋ฐ˜ํ™˜ return (ptr); }
C
๋ณต์‚ฌ

ย static char *do_split(char *ptr)

๊ฐœํ–‰ ๋ฌธ์ž๋ฅผ ํฌํ•จํ•˜์—ฌ ์ž๋ฅธ ๋’ค ์ž˜๋ผ์ง„ ๋ฌธ์ž์—ด์„ ๋ฐ˜ํ™˜
๋ฐ˜ํ™˜ ํ˜•ํƒœ
char * (๋ฌธ์ž์—ด ๋˜๋Š” NULL)
ํŒŒ๋ผ๋ฏธํ„ฐ
char *ptr โ†’ ์ž๋ฅผ ๋Œ€์ƒ
static char *do_split(char *ptr) { // ์ž˜๋ผ์งˆ ๋‚ด์šฉ์ด ๋“ค์–ด๊ฐˆ ๋ณ€์ˆ˜ char *line; // ๊ฐœํ–‰ ๋ฌธ์ž ๋˜๋Š” NULL๋ฌธ์ž๊ฐ€ ์žˆ๋Š” ์œ„์น˜ int idx; // line๊ณผ ptr์˜ ์œ„์น˜ int i; idx = 0; // ptr์˜ ๊ฐ’์ด NULL์ด๋ฉด NULL ๋ฐ˜ํ™˜ // ๋” ์ด์ƒ ์ฝ์„ ๊ฒƒ์ด ์—†๋‹ค๋Š” ๊ฒƒ if (*ptr == '\0') return (NULL); // ptr[idx]๊ฐ€ NULL, ๊ฐœํ–‰๋ฌธ์ž๊ฐ€ ์•„๋‹ ๋•Œ๊นŒ์ง€ ์ฆ๊ฐ€ while (ptr[idx] && ptr[idx] != '\n') idx++; // while๋ฌธ ์ข…๋ฃŒ ํ›„ idx์˜ ์œ„์น˜ ๋ฌธ์ž๊ฐ€ ๊ฐœํ–‰๋ฌธ์ž๋ฉด ํ•œ ๋ฒˆ ๋” ์ฆ๊ฐ€ // -> ๊ฐœํ–‰๋ฌธ์ž๋ฅผ ํฌํ•จํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•ด์ฃผ์–ด์•ผ ํ•ด์„œ if (ptr[idx] == '\n') idx++; // line ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น line = (char *)malloc((idx + 1) * sizeof(char)); if (!line) return (NULL); i = 0; // ptr๋‚ด์šฉ์„ line์œผ๋กœ ๋ณต์‚ฌ while (i < idx) { line[i] = ptr[i]; i++; } // ๋’ค์— ๋„ ๋ฌธ์ž ๋„ฃ๊ณ  ์ข…๋ฃŒ line[i] = '\0'; return (line); }
C
๋ณต์‚ฌ

ย static char *do_move(char *ptr)

์ž˜๋ผ์ง„ ๋ฌธ์ž์—ด ๋’ค๋กœ ptr[fd] ์ด๋™
๋ฐ˜ํ™˜ ํ˜•ํƒœ
char * (๋ฌธ์ž์—ด ๋˜๋Š” NULL)
ํŒŒ๋ผ๋ฏธํ„ฐ
char *ptr โ†’ ์ด๋™์ด ๋  ๋Œ€์ƒ
static char *do_move(char *ptr) { // ์ด๋™์ด ๋œ ๊ฒฐ๊ณผ char *str; // ๊ฐœํ–‰ ๋ฌธ์ž ๋˜๋Š” NULL์ด ์žˆ๋Š” ์œ„์น˜ int idx; // str๊ณผ ptr์˜ idx int i; idx = 0; // ๊ฐœํ–‰ ๋ฌธ์ž์™€ NULL๋ฌธ์ž๊ฐ€ ์•„๋‹ ๋•Œ๊นŒ์ง€ idx ์ฆ๊ฐ€ while (ptr[idx] && ptr[idx] != '\n') idx++; // ๋ฃจํ”„ ํ›„ ๊ฐœํ–‰๋ฌธ์ž๋ฅผ ๋งŒ๋‚˜๋ฉด ํ•œ ๋ฒˆ ๋” ์ฆ๊ฐ€ if (ptr[idx] == '\n') idx++; // NULL ๋ฌธ์ž๋ฉด ๋” ์ด์ƒ ์ฝ์„ ๊ฒƒ์ด ์—†๋‹ค๋Š” ๋œป์ด๋ฏ€๋กœ ptr ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ ํ›„ ์ข…๋ฃŒ if (ptr[idx] == '\0') { free(ptr); return (NULL); } // ptr ์ „์ฒด ๊ธธ์ด์—์„œ NULL๋ฌธ์ž ๋˜๋Š” ๊ฐœํ–‰ ๋ฌธ์ž ๋‹ค์Œ ์ž๋ฆฌ๋ถ€ํ„ฐ ๋งˆ์ง€๋ง‰๊นŒ์ง€์˜ ๊ธธ์ด๋งŒํผ ํ• ๋‹น // // 0 1 2 3 4 5 6 7 8 // a b c d e \n f g h // // 9 - 6 + 1 = 4๋งŒํผ ํ• ๋‹น // *str = "fgh" str = (char *)malloc((ft_strlen(ptr) - idx + 1) * sizeof(char)); if (!str) return (NULL); i = 0; while (ptr[idx]) str[i++] = ptr[idx++]; str[i] = '\0'; // ptr ํ•ด์ œ free(ptr); return (str); }
C
๋ณต์‚ฌ