Do You Coding?
[library] split ๊ตฌํํ๊ธฐ ๋ณธ๋ฌธ

๐ ๋งค๋ด์ผ (in subject)
Function name
do_split
Prototype
char **do_split(char const *s, char c);
Parameters
s: The string to be split. / c: The delimiter character.
: s ๋ ๋๋ ์ค ๋ฌธ์์ด, c๋ ๊ตฌ๋ถ์ ๋ฌธ์
Return value
The array of new strings resulting from the split. NULL if the allocation fails.
: ๋๋ ์ง ๊ฒฐ๊ณผ ๋ฌธ์์ด์ ๋ฐฐ์ด์ ๋ฐํ, ํ ๋น์ ์คํจํ๋ฉด NULL ๋ฐํ
External functs
malloc, free
Description
Allocates (with malloc(3)) and returns an array of strings obtained by splitting ’s’ using the character ’c’ as a
delimiter. The array must end with a NULL pointer.
: ํ ๋นํ๊ณ ๋ฌธ์ 'c'๋ฅผ ๊ตฌ๋ถ ๊ธฐํธ๋ก ์ฌ์ฉํ์ฌ 's' ๋ฅผ ๋ถํ ํด ์ป์ ๋ฌธ์์ด ๋ฐฐ์ด์ ๋ฐํํ๋ค.
๋ฐฐ์ด์ NULL ํฌ์ธํฐ๋ก ๋๋์ผ ํ๋ค.
๐ ์์ฑ ์ฝ๋
#include <stdlib.h>
#include <unistd.h>
static char **do_free(char **s)
{
int i;
i = 0;
while (s[i])
{
free(s[i]);
i ++;
}
free(s);
return (NULL);
}
static int do_wordcount(const char *s, char c)
{
int i;
int result;
i = 0;
result = 0;
while (s[i] != '\0')
{
if (s[i] != c && (s[i + 1] == c || s[i + 1] == '\0'))
result ++;
i ++;
}
return (result);
}
static char *do_strtok(char *s, char c, int *len, int *del_len)
{
char *tok;
*len = 0;
*del_len = 0;
tok = s;
while (*tok == c)
{
(*del_len)++;
tok ++;
}
while (*tok != c && *tok != '\0')
{
tok ++;
(*len)++;
}
*tok = '\0';
return (s);
}
static char **do_strtok_front(char *s, char c, int wordc)
{
int len;
int del;
char *str;
char **result;
int i;
i = 1;
result = (char **)do_calloc(sizeof(char *), (wordc + 1));
if (result == NULL)
return (NULL);
str = do_strtok(s, c, &len, &del);
result[0] = (char *)do_calloc(sizeof(char), (len + 1));
if (result[0] == NULL)
return (do_free(result));
do_strlcpy(result[0], str + del, len + 1);
while (i < wordc)
{
str = do_strtok(str + len + del + 1, c, &len, &del);
result[i] = (char *)do_calloc(sizeof(char), (len + 1));
if (result[i] == NULL)
return (do_free(result));
do_strlcpy(result[i++], str + del, len + 1);
}
return (result);
}
char **do_split(char const *s, char c)
{
char **result;
char *str;
int wordc;
if (s == NULL)
return (NULL);
str = do_strdup(s);
if (str == NULL)
return (NULL);
wordc = do_wordcount(str, c);
if (wordc == 0)
result = (char **)do_calloc(sizeof(char *), 1);
else
result = do_strtok_front(str, c, wordc);
if (result == NULL)
return (NULL);
free(str);
return (result);
}
๐ ์ฝ๋ ๋ฆฌ๋ทฐ
ํ์ด์ฌ, ์๋ฐ ๋ฑ์ ์กด์ฌํ๋ split ํจ์๋ฅผ c์์ ๋ง๋ค์ด๋ณด์๋ค.
๊ธฐ๋ณธ์ ์ธ ๋งค์ปค๋์ฆ์ string.h์ ์กด์ฌํ๋ strtok(split๊ณผ ๋น์ทํ ๋์์ ํ๋ ํจ์)์ ๊ฐ๋ ์ ํ ๋๋ก ๋ง๋ค์๋ค.
๋ฌธ์์ด(s)์ ๋ฐ์ ํน์ ๋ฌธ์(c)๋ก ๋จ์ด๋ค์ ๋๋๊ณ , ์ด์ฐจ์ ๋ฐฐ์ด์ ๊ฐ๊ฐ์ ๋จ์ด๋ฅผ ์ ์ฅํ๋ ํจ์์ด๋ค.
์ฐ์ , do_split ์์๋ถํฐ ์์ํ๋ค.
const๋ก ๋ฐ์์จ ๋ฌธ์์ด์ ์ง์ ์์ ํ ๊ฒ์ด๋ฏ๋ก, ์ด์ ์ ๋ง๋ do_strdup๋ฅผ ์ด์ฉํด ๋ณต์ฌํด ๋ฃ์ด์ค ๊ฒ์ด๋ค.
๊ทธ๋ ๊ฒ ๋ฌธ์์ด str์ด ๋ง๋ค์ด์ก๊ณ , ์ด str์ด ํ ๋น๋์ง ์์๋ค๋ฉด NULL์ ๋ฐํํ์ฌ ์์ธ์ฒ๋ฆฌํด์ค๋ค.
๊ทธ๋ฆฌ๊ณ ์๋ก ๊ตฌํํ do_wordcount ํจ์๋ฅผ ๊ฐ์ ธ์ wordc์ ๋ฃ์ด์ฃผ๋๋ฐ ์ด๋ ๊ฐ์ ธ์จ ๋ฌธ์์ด์ ๊ตฌ๋ถ์๋ฅผ ํตํด
๊ตฌ๋ถํ์ฌ, word์ ์๋ฅผ ํ์ ํ ์ ์๊ฒ ํด์ฃผ๋ ํจ์์ด๋ค. ๋ฐํ์ 'word ๊ฐ์'์ด๋ค.
๋ง์ฝ, ์ด wordc์ ๊ฐ์ด 0์ด๋ผ๋ฉด, ๋จ์ด๊ฐ ์กด์ฌํ์ง ์๋ ๊ฒ์ธ๋ฐ, ์ด ์ํฉ์์๋ result ์ do_calloc์ผ๋ก 1๋งํผ์ ๊ณต๊ฐ๋ง
ํ ๋นํ์ฌ, ๋น๋ฌธ์์ด์ ๋ฃ์ด์ค๋ค. ๊ทธ ์ธ์ wordc๊ฐ ์กด์ฌํ๋ค๋ฉด, else๋ฅผ ํตํด์ do_strtok_front ํจ์ ๋์์ผ๋ก ๋์ด๊ฐ๋ค.
do_strtok_front ํจ์์์๋ do_strtok๋ฅผ ๋ถ๋ฌ์ฌ ๋ฉ์ธ ๋์์ ๋ด๋นํ๋ค.
์ฐ์ ๋จ์ด๋ค์ ๋ด๊ธฐ ์ํด, ๋๋ธ ํฌ์ธํฐ char ํ์ผ๋ก do_calloc์ ํตํด result์ ํ ๋นํ๋ค. ํ ๋น์ ์คํจํ๋ฉด NULL์ ๋ฐํ.
๊ทธ๋ฆฌ๊ณ , do_strtok ๋์์ผ๋ก ๋์ด๊ฐ๋ค.
do_strtok ํจ์์์๋ ๊ธฐ์กด ๋ฌธ์์ด์ ์ฒซ ๋ถ๋ถ ์ฃผ์๋ฅผ ๊ฐ์ ธ์ tok ์ ๋จผ์ ํ ๋นํ๋ค.
ํ ๋นํ *tok๊ฐ c์ ํด๋นํ๋ ๋ฌธ์์ ํด๋น๋๋ฉด tok์ ์ฃผ์๊ฐ์ ์ฆ๊ฐ์์ผ์ฃผ๊ณ ,
del_len์ผ๋ก ์ค์ ํ '๊ตฌ๋ถ์๊ฐ ๋์ค๋ ๊ธธ์ด ๊ฐ'๋ ์ฆ๊ฐ์์ผ์ค๋ค.
-> ์ด๋ ๊ตฌ๋ถ์๊ฐ ์ฌ๋ฌ๋ฒ ์ด์ด ์์ฑ๋์์ ๋, ๋จ์ด ์ ์ฅ์ ๊ตฌ๋ถ์๊ฐ ํฌํจ๋์ด ์ ์ฅ๋์ง ์๋๋ก ํด์ฃผ๊ธฐ ์ํจ์ด๋ค.
(do_strtok_front ํจ์์์ result์ ์ ์ฅํ ๋ + del ์ด ๋๋ฉด์ ๊ตฌ๋ถ์ ๋ถ๋ถ์ ๋นผ์ค๋ค.)
๊ทธ๋ฆฌ๊ณ ๋จ์ด๊ฐ ๋์ค๋ ๋ถ๋ถ (*tok์ด c๊ฐ ์๋ ๋ถ๋ถ)๊ณผ ํด๋น ์์น๊ฐ null์ด ์๋ ๊ฐ์ด ์กด์ฌํ๋ ๋์ tok ์ฃผ์๊ฐ์ ์ฆ๊ฐํ๋ฉฐ
๋จ์ด ๊ธธ์ด์ธ len๋ ์ฆ๊ฐ์์ผ์ค๋ค. (์ด๋ ์ถํ์ ๋์ ํ ๋น์ ์ํด len์ ๊ฐ์ ธ์ค๊ธฐ ์ํจ.)
(-> *len ++ ๋ก ํ๋ฉด ์ฃผ์๊ฐ len์ ์๋ฃํ๋งํผ ์ฆ๊ฐ ๋๋๊ฑฐ๊ณ , (*len) ++ ๋ฅผ ํด์ผ ํด๋น len์ ๊ฐ์ด ์ฆ๊ฐ๋๋ค.)
tok ๋ก ๊ฐ๋ฆฌํค๋ ๋ง์ง๋ง ๋ถ๋ถ์ '\0'๋ฅผ ๋ฃ์ด์ฃผ๋ฉด์ ๋จ์ด๋ฅผ ๋์ด์ฃผ๊ณ , ๊ธฐ์กด ๋ฌธ์์ด ์ฒซ ์ฃผ์๋ฅผ ๊ฐ๋ฆฌํค๋ s๋ฅผ ๋ฐํํ๋ค.
๊ทธ๋ฆฌ๊ณ ๋ค์ do_strtok_front๋ก ๋์๊ฐ result[0] ๋ถ๋ถ์ ๋ฐฉ๊ธ ๊ตฌํ len + 1 ๋งํผ do_calloc์ผ๋ก ํ ๋นํด์ฃผ๊ณ ,
์์ธ์ฒ๋ฆฌ ํ do_strlcpy๋ก ๋จ์ด๋ฅผ copyํด์ ๋ฃ์ด์ค๋ค. ์ฌ๊ธฐ์ ์ธ์๋ฅผ ๋ณด๋ฉด,
result[0]์ ๋ณต์ฌํ์ฌ ๋ฃ์ ๊ฒ์ด๊ณ , str ์์ del ๋งํผ๋ง ๋ํด์ค์ ์ฒซ ๋จ์ด์ ์ฒซ ์์น๋ถ๋ถ์ ๊ฐ๋ฆฌํค๋๋ก ํ๊ณ ,
๊ทธ ์์น์์๋ถํฐ len + 1๊น์ง๋ง ์ฝ์ด์ copy ํด์ค๋ค.
๊ทธ๋ผ result[0]์๋ ์ฒซ ๋จ์ด๊ฐ ์ ์ฅ์ด ๋ ๊ฒ์ด๊ณ , ์ด๋ฌํ ๊ณผ์ ๋ค์ while์ ํตํด์ wordc ๊น์ง ๋ฐ๋ณตํ๋ฉด ๋์ด๋ค.
while ๋ฌธ์์๋ do_strtok์ str + len + del + 1 ์ด๋ผ๋ ์ธ์๋ฅผ ๋ฃ๊ฒ ๋๋๋ฐ, ๋ฐฉ๊ธ ๊ตฌํด์ง len๊ณผ del ๊ทธ๋ฆฌ๊ณ +1 ์ ํด์
์ฒซ๋ฒ์งธ ๋ฌธ์๊ฐ ๋๋ ๋ค์๋ถ๋ถ ๋ถํฐ ์ฝ์ด๊ฐ๋๋ก ํ๋ค. ๊ทธ๋ฆฌ๊ณ ๊ฐ์ ๊ณผ์ ์ ์ํํ๊ณ , while๋ฌธ์ด ๋ ๋๋ง๋ค
do_strtok ์ธ์์ ๋ค์ด๊ฐ str์ด str + len + del + 1 ๋ก ๋ฐ๋์ด ๋ค์ด๊ฐ๋ฏ๋ก, ๋ค์ ๋จ์ด๋ฅผ ๊ณ์ ๋ณผ ์ ์๊ฒ ๋๋ค.
๋ชจ๋ ๋จ์ด๋ฅผ ์ฝ๊ณ ๋๋ฉด result๋ฅผ ๋ฐํํ๋ค.
do_split์ผ๋ก ๋์์์ ์์ธ์ฒ๋ฆฌ๋ฅผ ํด์ฃผ๊ณ , free(str)๋ก str์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋น์์ค๋ค.
(์ด์ ์ str์ free ํ์ง ์์์ ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ์์๋๋ฐ, ์ด๋ฅผ ์ถ๊ฐํ์ฌ alloc ๊ณผ free๊ฐ ์ ์์๋ํ์ฌ leak๊ฐ ์๊ฒ ํ๋ค.)
๊ทธ๋ฆฌ๊ณ result๋ฅผ ๋ฐํํ๋ฉด์ ๋ชจ๋ ๋จ์ด๋ค์ด result์ ๊ฐ๊ฐ ์ ์ฅ๋์ด split์ด ์ํ๋์ด์ง๋ฉด์ ๋๋๋ค.
์ฝ๋๊ฐ ์ฌํ ๊ธธ์ด์ง๊ณ ๋ถํ์ํ ๋ถ๋ถ์ด ๋ง์์ง ์ ์ด ์์ฝ๊ธฐ ๋๋ฌธ์ ์ถํ์ ์ฌ์์ฑํด๋ณผ splitํจ์ ์ด๋ค.
strtok ๊ฐ๋ ์ ๊ผญ ํ์ฌํ๊ณ ์ถ์ด์, ๋ ์ฝ๊ฒ ๊ฐ ์ ์๋๋ฐ ๋์๊ฐ ๋ถ๋ถ์ด ์์ง ์์ ์๋ค.
split์ ๊ธฐ๋ณธ๋์๋ง ์๊ฐํ๊ณ ์ถํ์ ๋ค์ ์์ฑํด๋ณด๋๋ก ํ๊ฒ ๋ค.
'CS & Engineering > C' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| [utility] get_next_line ๊ตฌํํ๊ธฐ (3) | 2024.08.31 |
|---|---|
| [library] itoa ๊ตฌํํ๊ธฐ (0) | 2024.06.29 |
| [library] strtrim ๊ตฌํํ๊ธฐ (0) | 2024.06.27 |
| [library] strjoin ๊ตฌํํ๊ธฐ (0) | 2024.06.26 |
| [library] substr ๊ตฌํํ๊ธฐ (0) | 2024.06.18 |