뇌 마음 반반저장소

[42_libft] Part 2 (split 자세한 설명) 본문

42/libft

[42_libft] Part 2 (split 자세한 설명)

맹진저 2022. 12. 12. 17:32
728x90

1-4. ft_split

split이란?

Parameters : 매개 변수
s: The string to be split.
s: 분할할 문자열입니다.
c: The delimiter character.
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'를 분할하여 얻은 문자열 배열을 할당하고(malloc(3)) 반환합니다. 배열은 NULL 포인터로 끝나야 합니다.

함수 선언 원형

char	**ft_split(char const *s, char c);

문자 c를 사용하여 s를 분할한다.. 나에게 첫 번째 떠오르는 질문은 '그렇다면 문자 c는 포함인가?'였다.

답은 '아니다'이다. 문자 c는 분할하는 기준점이 되고 문자열에 포함되지 않고 버려진다. 그러면 문자열을 계산할 때 각 줄에 '\0'을 추가하기 위한 줄 * '\0' 개수는 해주지 않아도 된다!

 

내가 생각한 작문은 이렇다. 일단 동적 할당해서 빌려줄 자리를 만들어보자. 그렇다면

1. 문자열이 얼마나 있는지 확인한다. 

 이때 중요한 것은 c와 같거나, c의 다음 문자가 널문자거나, 다음문자가 c와 같지 않을 때 복사할 수 있다.

 

예를 들어서 111iam111split111이라는 문자열이 있고 1마다 분할한다면

 

 

 

iam

 

 

 

split

 

 

 

요렇게 될 것이다. 하지만 split이 원하는 결과는 바로

iam

split

이다. 그래서 우리는 동일한 c문자가 여러 개 나오면 하나로 생각해서 한 번만 '\0'을 할당하면 된다.

이렇게 살리고 싶은 배열을 일단 모두 카운트한다!

 

2. 카운트 한 만큼 이차원 배열을 만들어 준다. 

나는 공부하면서 다시 한번 충격을 받았다. 사실 다른 캬뎃들의 ft_split을 보면서 왜 저렇게 쓰였는지, 그리고 왜 이렇게 썼는지 근본적으로 접근하는 블로거나 친구들을 못 봤다. 

ft_split의 목적은 바로 2차원 배열에 동적 할당을 하는 법을 숙지하는 일이다. (이건 약간 수학공식 같은 것이니 토 달지 말자 나 자신)

 

1. 1차원 배열이 할당되고 해제되는 순서

1차원 배열을 할당하는 방법은 쉽다. 한 개의 행(y)과 여러 개의 열(x)이 있기 때문에 아래와 같이 할당하면 된다.

int x = 9;
char *str;

str = (char *)malloc(sizeof(char) * (9 + 1));
str = "I'm split";

위에 저렇게 malloc으로 방을 빌려주고 문자열을 할당하면 아래와 같이 적혔을 것이다.

I ' m   s p l i t \0

그리고 아래와 같이 해제한다. 

free(str);

 

2. 2차원 배열이 할당되고 해제되는 순서

 1. 2차원 배열은 먼저 행(y 또는 row)을 건설해준다. 

int y = 3;
char **2d_array;

2d_array = (char **)malloc(sizeof(char *) * 3);

그러면 지금 현재 빌린 방의 상태는 이렇다. 세로로 일단 세 칸만 빌린 것이다. 

 
 
 

 

 2. 그다음 x열을 만들어 준다.

int	i;
int x = 9;

i = 0;
while(i < row)
{
	2d_array[i] = (int *)malloc(sizeof(int) * (x + 1));
	i++;
}

그렇다면 이렇게 \0자리 가지 10개씩 방이 빌려졌다. 

                   
                   
                   

참고로 split을 짤 때는 문자열을 훑으면서 c가 아니면 방에 문자를 집어넣고, c이면 널을 할당 해서 필요한 만큼만 행을 채워나간다. 

 

3. 해제하기 - x열 하나씩 해제하기

int	i;

i = 0;
while(2d_array[i])
{
	free(2d_array[i])
	i++;
}

4. 해제하기 - y행 해제하기

free(2d_array)

이렇게 메모리를 해제하지 않으면 메모리 누수가 일어난다.. 그래서 우리가 할당한 방향에 반대로 해제해 주면 된다.  (컴퓨터는 섬세한 친구..)

 

5. 다른 방법 - 한꺼번에 배열 만들기

2d_array = (char *)malloc(sizeof(char) * y * x);

이 방법은 필요하면 아래의 블로그에 들어가 보자. 많은 카뎃들이 이 방법으로 split을 두 개로 나누어 사용한다. 하지만 나는 왕초보이기 때문에 쉽고 간결한 방법으로 설명해보겠다..

진짜 이차원 배열처럼 malloc 하는 방법

 

자 그러면 이제 카운트 한 만큼 2차열 배열(y)을 만들어주고

while문으로 1차원 배열(x)에 문자열을 하나씩 넣어 보자!

그리고 조건과 일치하지 않을 경우 2차원 배열을 해제해 주는 메모리 해제 함수도 만든다.

 

!테스트 메인!

int main()
{
    char    **array;
    int     i;

	printf("before split : abc1def1ghi\n");
	printf("split letter : 1\n");
    array = ft_split("abc1def1ghi", '1');
    i = -1;
    while (array[++i] != NULL)
	    printf("%s\n", array[i]);
    free(array);

	printf("\n");
    printf("before split : 111iam111not111hero1111\n");
	printf("split letter : 1\n");
    array = ft_split("111iam111not111hero1111", '1');
    i = -1;
    while (array[++i] != NULL)
	printf("%s\n", array[i]);
    free(array);
	return 0;
}

사용한 함수

1. 카운트용 함수 : 조건에 맞는 문자열을 세는 함수를 따로 만들었다. 기능은 strlen과 비슷.

2. malloc : 힙 공간을 잡아준다.

3. 쓰는 함수 :  조건에 맞다면 malloc으로 공간을 할당하고, x열에 문자를 차례로 넣어준다.

4. free함수 : 2차원 배열을 해제해주는 함수를 따로 만들었다.

 

!테스트 결과!

$ ./main.out
before split : abc1def1ghi
split letter : 1
abc
def
ghi

before split : 111iam111not111hero1111
split letter : 1
iam
not
hero

 

도움을 주고 싶으신 내용이나

틀린 내용이 있다면 댓글로 남겨주시고,

참고하신다면 꼭 출처를 밝혀주세요!

 

도움이 되었다면 공감 한 번씩 부탁드립니다❤️

728x90

'42 > libft' 카테고리의 다른 글

[42_libft] Part 2 (strmapi, striteri 함수포인터 알아보기)  (0) 2022.12.14
[42_libft] Part 2 (itoa)  (0) 2022.12.13
[42_libft] Part 2 (strtrim)  (0) 2022.12.11
[42_libft] Part 2 (substr, strjoin)  (0) 2022.12.11
[42_libft] Part 1 (mem 함수들)  (1) 2022.12.09
Comments