728x90
split
함수 형태
char **my_split(char const *s, char c);
매개 변수
- 분할할 문자열
- 구분 기호 문자
반환 값
분할한 새 문자열 배열, 할당 실패시 NULL 반환
설명
malloc(3)로 할당하고 문자 'c'를 구분 기호로 사용하여 's'를 분할하여 얻은 문자열 배열을 반환하십시오. 배열을 NULL 포인터로 종료해야 함
소스 코드
#include "libmy.h"
static int get_row(char const *s, char c)
{
size_t i;
size_t ret;
i = 0;
ret = 0;
while (s[i])
{
if (s[i] != c && (s[i + 1] == c || !s[i + 1]))
ret++;
i++;
}
return (ret);
}
static int get_split(char const *s, char c, char **ret)
{
char *flag;
size_t col;
size_t i;
size_t j;
col = 0;
i = 0;
j = 0;
flag = 0;
while (*s)
{
if (*s != c)
{
if (!flag)
flag = (char *)s;
col++;
if(*(s + 1) == c || !*(s + 1))
{
if (!(ret[i] = (char *)my_calloc(col + 1, sizeof(char))))
return (0);
while (j < col && flag[j])
{
ret[i][j] = flag[j];
j++;
}
i++;
flag = 0;
col = 0;
j = 0;
}
}
s++;
}
return (1);
}
char **my_split(char const *s, char c)
{
char **ret;
size_t row;
row = 0;
while (*s && *s == c)
s++;
if (!(row = get_row(s, c)))
return ((char **)s);
if (row == my_strlen(s) || !s)
return (0);
if (!(ret = (char **)my_calloc(row + 1, sizeof(char))))
return (0);
if (get_split(s, c, ret))
return (ret);
else
return (0);
}
테스트 케이스를 돌렸을 때 segmentation fault가 떳다. 이유가 뭘까.. 직접 넣어본 테스트는 잘 되는거 같았는데 너무 어렵다...
다 지우고 코드를 다시 작성해봤다.
#include "libmy.h"
static char **my_free_malloc_error(char **ret)
{
size_t i;
i = 0;
while (ret[i])
{
free(ret[i]);
i++;
}
free(ret);
return (NULL);
}
static size_t my_get_row(char const *s, char c)
{
size_t ret;
size_t i;
ret = 0;
i = 0;
if (!*s)
return (0);
while (s[i] && s[i] == c)
i++;
while (s[i])
{
if (s[i] == c)
{
ret++;
while (s[i] && s[i] == c)
i++;
}
else
i++;
}
if (s[i - 1] != c)
ret++;
return (ret);
}
static size_t my_get_strlen(char const *s, char c)
{
size_t i;
i = 0;
while (s[i])
{
if (s[i] == c)
break ;
i++;
}
return (i);
}
char **my_split(char const *s, char c)
{
char **ret;
size_t len;
size_t row;
size_t i;
if (!s)
return (NULL);
row = my_get_row(s, c);
if (!(ret = (char **)malloc(sizeof(char *) * (row + 1))))
return (NULL);
i = 0;
while (i < row)
{
while (*s && *s == c)
s++;
len = my_get_strlen(s, c);
if (!(ret[i] = (char *)malloc(sizeof(char) * len + 1)))
return (my_free_malloc_error(ret));
my_strlcpy(ret[i], s, len + 1);
i++;
if (i < row)
s += len;
}
ret[i] = (NULL);
return (ret);
}
문제를 다시 읽어보니 malloc함수를 이용하여 풀으라고 돼있었다. segfault의 원인은 아마 스플릿 문자 확인할 때 다음 문자확인용도로 +1 했던게 문제가 아닐까 싶다.
그리고 또 중요한 것은 메모리 할당에 실패했을 때 누수 처리도 해주어야한다. 행에 대한 누수처리는 실패시 NULL을 반환하면 되지만 열에 대한 누수처리는 그 전까지 할당된 메모리를 모두 해제해야한다.
하지만 abort 에러가 떳다. 그 이유는 strlcpy에 있었다.
size_t my_strlcpy(char *dst, const char *src, size_t size)
{
const char *s;
char *d;
size_t n;
d = dst;
s = src;
n = size;
if (!dst && !src)
return (0);
if (n != 0)
{
while (--n != 0)
{
if ((*d++ = *s++) == '\0')
break ;
}
}
if (n == 0)
{
if (size != 0)
*d = '\0';
while (*s++)
;
}
return (s - src - 1);
}
while(*s++)
을 하게되면 조건에서 *s
가 널문자임을 확인하고 다음으로 넘어가버려서 문제가 됐었다.
코드 수를 줄이고 좀 간편하게 풀려고 하다가 틀리는 경우가 많다. 정말 사소한부분까지 잘 보면서 문제를 풀어야한다.
728x90
300x250