Do You Coding?
[utility] get_next_line ๊ตฌํํ๊ธฐ ๋ณธ๋ฌธ

๐ ๋งค๋ด์ผ (in subject)
Function name
get_next_line
Prototype
char *get_next_line(int fd);
Parameters
fd: The file descriptor to read from
: ์ฝ์ด์จ ํ์ผ ๋์คํฌ๋ฆฝํฐ
Return value
Read line: correct behavior / NULL: there is nothing else to read, or an error occurred
: ์ฌ๋ฐ๋ฅธ ๋์์ ์ค 1์ค ์ฝ์ด์ค๋ ๊ฒ์ด๊ณ , ์ฝ์ ๊ฒ ์๊ฑฐ๋ ์๋ฌ๊ฐ ๋ฐ์ํ๋ฉด NULL์ ๋ฐํํ๋ค
External functs
read, malloc, free
Description
Write a function that returns a line read from a file descriptor
: ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ก๋ถํฐ ์ฝ์ด์ ํ์ค์ ๋ฐํํ๋ ํจ์๋ฅผ ์์ฑํ๋ค
๐ ์์ฑ ์ฝ๋ (1) - header file code
#ifndef GET_NEXT_LINE_H
# define GET_NEXT_LINE_H
# ifndef BUFFER_SIZE
# define BUFFER_SIZE 10
# endif
# include <stdlib.h>
# include <unistd.h>
size_t do_strlen(const char *s);
char *do_strdup_s(char *str, char *buff);
char *do_strljoin(char *s1, char *s2, int rs);
size_t do_strlcpy(char *dst, const char *src, size_t size);
char *get_next_line(int fd);
#endif
๐ ์์ฑ ์ฝ๋ (2) - utils code
#include "get_next_line.h"
size_t do_strlen(const char *s)
{
size_t i;
i = 0;
while (s[i] != '\0')
i ++;
return (i);
}
char *do_strdup_s(char *str, char *buff)
{
char *dup;
size_t buff_len;
size_t i;
buff_len = do_strlen(buff);
i = 0;
dup = (char *)malloc(sizeof(char) * (buff_len + 1));
if (dup == NULL)
return (NULL);
while (buff[i] != '\0')
{
dup[i] = buff[i];
i ++;
}
dup[i] = '\0';
if (str != NULL)
free (str);
return (dup);
}
char *do_strljoin(char *s1, char *s2, int rs)
{
char *s3;
size_t i;
size_t len_s1;
i = 0;
len_s1 = do_strlen(s1);
if (!s1 || !s2)
return (NULL);
s3 = (char *)malloc(sizeof(char) * (len_s1 + rs + 1));
if (s3 == NULL)
return (NULL);
while (i < len_s1)
{
s3[i] = s1[i];
i ++;
}
while (i < len_s1 + rs)
{
s3[i] = s2[i - len_s1];
i ++;
}
free (s1);
s3[i] = '\0';
return (s3);
}
size_t do_strlcpy(char *dst, const char *src, size_t size)
{
size_t i;
i = 0;
while (i + 1 < size && src[i] != '\0')
{
dst[i] = src[i];
i ++;
}
if (size != 0)
dst[i] = '\0';
return (do_strlen(src));
}
๐ ์์ฑ ์ฝ๋ (3) - main code
#include "get_next_line.h"
static int read_and_store(int fd, char **str)
{
char buff[BUFFER_SIZE + 1];
int rs;
rs = read(fd, buff, BUFFER_SIZE);
if (rs <= 0)
return (rs);
buff[rs] = '\0';
if (*str == NULL)
*str = do_strdup_s(*str, buff);
else
*str = do_strljoin(*str, buff, rs);
return (rs);
}
static char *put_next_line(char **str, size_t len, size_t i)
{
char *restr;
restr = NULL;
i ++;
restr = malloc(i + 1);
if (restr == NULL)
return (NULL);
do_strlcpy(restr, *str, i + 1);
if (i - 1 == len)
{
free (*str);
*str = NULL;
}
else if (i - 1 != len)
*str = do_strdup_s(*str, *str + i);
return (restr);
}
char *get_next_line(int fd)
{
static char *str = NULL;
int rs;
size_t len;
size_t i;
while (1)
{
rs = read_and_store(fd, &str);
if (str[fd] != NULL)
len = do_strlen(str);
if (rs == -1 || (rs == 0 && str == NULL) || (len == 0))
{
free (str);
str = NULL;
return (NULL);
}
i = 0;
while (str[i] != '\n' && i < len)
i ++;
if ((i == len && (rs < BUFFER_SIZE)) || (i != len))
return (put_next_line(&str, len, i));
}
}
๐ ์ฝ๋ ๋ฆฌ๋ทฐ
- char *get_next_line(int fd)
โ ๋์ : ์ธ์๋ก ๋ฐ์์จ ํ์ผ ๋์คํฌ๋ฆฝํฐ(fd)๋ก ์ฝ์ด์จ ํ์ผ์์, ๊ฐํ์ ์ฐพ์๊ฐ๋ฉฐ 1์ค ์ฉ ๋ฐํํด์ฃผ๋ ํจ์
โ ์ฃผ์ ๊ณผ์ : static์ผ๋ก ๋ด๋ถ์ ์ ๋ณ์ str์ ์ ์ธํ๊ณ , while(1)์ ํตํด ๋ฌดํ ๋ฐ๋ณต๋ฌธ์ ๋๋ฆฐ๋ค.
๊ทธ ํ, read_and_store ํจ์์์ BUFFER_SIZE ๋งํผ readํ์ฌ buff ๋ฌธ์์ด์ ๋ด์์ค๋ค.
str์ด ๋น์ด์์ผ๋ฉด (=NULL) strdup์ผ๋ก ์๋ก ๋ด์์ฃผ๊ณ , ๋น์ด์์ง ์์ผ๋ฉด strljoin์ผ๋ก ๋ถ์ฌ์ค๋ค.
๊ทธ๋ฆฌ๊ณ ์ฝ์ read_size๋ฅผ ๋ฐํํ์ฌ ํด๋น ๊ฐ์ ๋ฐ๋ผ ์์ธ ์ฒ๋ฆฌ๋ฅผ ํด์ฃผ๊ณ , ๊ฐํ์ด ํด๋น str์ ํฌํจ๋์ด ์์ผ๋ฉด
put_next_line ํจ์๋ฅผ ์คํํ๋ค. ํด๋น ํจ์์์๋ ํ์ฌ str์์ ๊ฐํ ์ ๊น์ง ๋ฌธ์์ด์ ๋ฐํํ๊ณ ,
๊ฐํ ์ดํ์ ๋ฌธ์์ด๋ง str์ ๋จ๊ฒจ๋๋ ์ญํ ์ ํ๋ค. ๋ง์ฝ ์์์ str์ ๊ฐํ์ด ํฌํจ ๋์ด์์ง ์๋ค๋ฉด,
while๋ฌธ์ ๋ค์ ์คํํ์ฌ ๋ค์ read_and_store ํจ์๋ฅผ ์คํํ์ฌ BUFFER_SIZE๋งํผ readํ๋ ๊ณผ์ ์ ๋ฐ๋ณตํ๋ค
๊ฐํ์ ๋ง๋ ๋ฐํํ ๋๊น์ง ์ํํ๋ค.
โ ์ค๋ช
- ์ฐ์ , static์ ํตํด ํจ์ ๋ด์ ๋ง๋ ๋ด๋ถ์ ์ ๋ณ์๋ ํ๋ก๊ทธ๋จ์ด ์์๋ ๋ ํ ๋น๋๊ณ , ์ข
๋ฃํ ๋ ํด์ ๋๋ค.
๋ฐ๋ผ์ ์ฌ๋ฌ๋ฒ ํจ์๋ฅผ ์คํํด๋, ํ๋ฒ๋ง ์ด๊ธฐํ๋๋ฏ๋ก ์ด๋ฅผ ํ์ฉํด ๊ฐํ ์ดํ์ ๋ฌธ์์ด์ ๋ด์๋๋ ์ญํ ์ ํ๋ค.
- while๋ฌธ์ ๋ฌดํ ๋ฐ๋ณต์ผ๋ก ํ์ฌ ๊ณ์ ์คํํ๊ฒ ๋๋๋ฐ, ๊ฐํ์ ๋ง๋์ put_next_line ํจ์์ ๋ฐํ๊ฐ์ ๋ฐํํ๋ฉด
๊ทธ๋ ์ข ๋ฃ๋๋ค. get_next_line ํจ์๊ฐ ์ข ๋ฃ๋์ด๋ ์์์์ ์ธ๊ธ์ฒ๋ผ ๋ด๋ถ์ ์ ๋ณ์์ด๋ฏ๋ก,
ํ๋ก๊ทธ๋จ ์ข ๋ฃ๊น์ง static์ด ์ ์ง๊ฐ ๋๋๋ฐ, ์ฒซ ์ค์ด ๊ฐํ์ ๋ง๋ get_ next_line์ ์ฒ์ ๋ฐํํ๋ค๊ณ ํด๋,
static ๋ณ์์ ๊ทธ ๊ฐํ ์ดํ์ ๊ฐ์ด ๋จ์์์ ์ ์๋ค.
(Buffer ํฌ๊ธฐ๋งํผ read๋ฅผ ๋ฐ๋ณตํ๋ฏ๋ก, buffer ํฌ๊ธฐ์ ๋ฐ๋ผ ๊ฐํ ์ดํ์ ๋ฌธ์์ด์ด ๋จ์ ์์ ์ ์๋ค.)
- ์ด static ์ผ๋ก ์ ์ธํ ๋ฌธ์์ด์ ๊ฐํ์ด ์ค๊ฐ์ ์๋ค๋ฉด ๊ทธ ์ดํ์ ๋ฌธ์์ด๋ง static๋ณ์์ ๋จ๊ฒจ๋๋ ๊ณผ์ ์ด ํ์ํ๋ค.
๋ค์ get_next_line์ ๋ถ๋ฌ์์ ๋, static์ ์๋ ๋ฌธ์์ด ๋ค๋ก ์๋ก ์ฝ์ด์จ ๋ฌธ์์ด์ ๋ถ์ฌ์ผ ์ ์์ ์ผ๋ก
๋ค์ ์ค์ ๊ฐ์ ธ์ฌ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
- ์คํ ์, buffer size๋ฅผ ํฐ๋ฏธ๋์์ ํ์ค์ ๋ ฅ์ผ๋ก ๋ฐ์์ ์ ์ฉํ๋๋ฐ, ์ด ์ ๋ ฅ๊ฐ์ด ์กด์ฌํ์ง์์ ๋๋
header์์ define์ด ๋์ง ์์์ ๋ 10์ผ๋ก ๊ธฐ๋ณธ๊ฐ์ ์ง์ ํด๋์๋ค.
- util๋ค์ ํ์ธํด๋ณด๋ฉด, ๊ธฐ์กด ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋ง๋ค์ด๋๋ str ๊ด๋ จ ํจ์๋ค๊ณผ ๋ค๋ฅด๊ฒ ๊ฐ์ ธ์จ string์ freeํด์ฃผ๋ ๊ณผ์ ์
์ถ๊ฐํด๋์๋ค. ๊ธฐ์กด์ ์กด์ฌํ๋ string์ freeํด์ฃผ๊ณ ์๋ก ํ ๋น๋ ๋ฌธ์์ด์ ๋ฐํํ๋ ์์ ๋ฑ์ ํ๊ธฐ์ํด ์ ์ฉํ์๋ค.
โ ํ๊ณ
- 3 ~ 4๋ฌ ์ ์ ์ง ํจ์๋ผ ์ง๊ธ ๋ณด๋ ์ ๋ฆฌ๊ฐ ๊น๋ํ๊ฒ ๋์ด์์ง ์๋ค๋ ๋๋์ด ์๊ธด ํ๋ค.
๋ํ, ๋ถํ์ํ ๋ถ๋ถ์ด ์กด์ฌํ๋ฉฐ, buffer๋งํผ ๊ณ์ ์ฝ๋ ๊ฒ๋ณด๋ค๋, ์ด๋ฏธ str์ ๊ฐํ์ด ์กด์ฌํ๋ฉด ์ฝ์ง ์๊ณ ๋ฐ๋ก
put_next_line์ผ๋ก ๋๊ฒจ์ฃผ๋ ๊ฒ์ด ์ข์ ๊ฒ ๊ฐ๋ค. ์๋ฌด๋๋ ์ด๋ฐ์์ผ๋ก ๋ฐ๊พธ๋ ค๋ฉด ์๋ก ๋ค ๋ฐ๊ฟ์ผํ ๊ฒ ๊ฐ์๋ฐ,
์ถํ์ ์๊ฐ์ด ๋๋ฉด 'get_next_line_renewal_ver'๋ก ์๋ก ๋ง๋ค์ด๋ด์ผ๊ฒ ๋ค. (...)
'CS & Engineering > C' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| [function] pthread_join ํจ์ ์์๋ณด๊ธฐ (8) | 2024.09.07 |
|---|---|
| [function] pthread_create ํจ์ ์์๋ณด๊ธฐ (5) | 2024.09.07 |
| [library] itoa ๊ตฌํํ๊ธฐ (0) | 2024.06.29 |
| [library] split ๊ตฌํํ๊ธฐ (0) | 2024.06.29 |
| [library] strtrim ๊ตฌํํ๊ธฐ (0) | 2024.06.27 |