char *strdup(char *src)
strdup은 문자열 src를 복사하기 위해 메모리를 할당하고 (malloc 사용), 그곳에 src를 복사한다. 그리고 그 만들어진 문자열 포인터가 가르키는 곳을 반환한다.
과정
우선 src의 길이를 재고 null자리를 포함하여 동적할당 진행.
아무 것도 할당되지 않았다면 null을 return.
그 후 새로운 문자열에 복사 진행하고 null을 붙여준 뒤 반환하면 된다.#include <stdlib.h> char *reproduce_strdup(char *src) { char *new_src; int src_length; int i; src_length = strlen(src); new_src = (char *)malloc(src_length + 1 * sizeof(char)); if (!(new_src)) return (0); i = 0; while (src[i]) { new_src[i] = src[i]; ++i; } new_src[i] = '\0'; return (new_src); }
char *strjoin(int size, char **strs, char *sep)
매개 변수로 받은 문자열 배열을 size개수만큼 sep으로 이어서 하나의 문자열로 만든 뒤 반환한다.
과정
우선 malloc을 위해 size를 재는 함수를 작성한다.int malloc_size_cal(int size, char **strs, char *sep) { int strs_len; int sep_len; int i; strs_len = 0; sep_len = strlen(sep); //sep의 길이를 따로 재어놓음 i = 0; if (size == 1) return (strlen(strs[0]) + 1); //size가 1일때 null만 붙여서 반환 while (i < size - 1) { strs_len += strlen(strs[i]); strs_len += sep_len; ++i; } strs_len += strlen(strs[i]); return (strs_len + 1); //null자리 고려하여 반환 }
계산한 size를 이용하여 동적할당을 진행하고 join한다.
char *poduce_strjoin(int size, char **strs, char *sep) { int total_length; int i; char *str; if (size == 0) { str = (char *)malloc(1); str[0] = 0; return (str); } total_length = malloc_size_cal(size, strs, sep); //위 함수 활용 str = (char *)malloc(total_length * sizeof(char)); i = 0; if (*(str + i) != 0) //새로 동적할당 받은 주소에 쓰레기값이 있으면 밀기위해 *(str + i) = 0; i = 0; while (i < (size - 1)) { str = strcat(str, *(strs + i)); str = strcat(str, sep); ++i; } str = strcat(str, *(strs + i)); return (str); }
char **split(char *str, char *sep)
매개 변수로 받은 문자열을 seperator로 쪼갠다. 이때 문자열 sep 문자 하나 하나가 구분자 역할을 한다.
과정
우선 반환타입이 char **이므로, 즉 문자열의 주소를 담고 있는 배열을 반환한다고 생각할 수 있다. 따라서 문자열 포인터를 배열 개수만큼 동적할당해줘야 한다. 이때 배열의 개수는 쪼갤 단어의 개수 + 1(null)이다.그럼 단어의 개수를 세는 함수 먼저 작성해보자.
int is_sep(char c, char *sep) { int i = 0; while (sep[i]) { if (sep[i] == c) return (1); ++i; } return (0); } int count_words(char *str, char *sep) { int i = 0; int count = 1; //단어 개수는 1개부터 시작이므로 while (str[i] != '\0') { if (is_sep(str[i], sep) && !is_sep(str[i + 1], sep)) ++count; ++i; } return (count); }
계산한 size를 이용하여 동적할당을 진행한다.
char **split(char *str, char *sep) { char **str_arr; //할당 후 반환할 변수 int arr_i; int i; int word_num; //malloc할 size word_num = count_words(str, sep); str_arr = (char **)malloc((word_num + 1) * sizeof(char *)); //null자리 하나 붙여서 char\*를 곱해줌 arr_i = 0; i = 0; while (*(str + i)) { while (*(str + i) && is_sep(*(str + i), sep)) ++i; if (*(str + i) && !is_sep(*(str + i), sep)) { str_arr[arr_i] = make_str((str + i), sep); ++arr_i; } while (*(str + i) && !is_sep(*(str + i), sep)) ++i; //다음 sep을 만날 때까지 index를 점프시킨다. } str_arr[arr_i] = 0; return (str_arr); }
한 단어씩 string으로 만드는 make_str함수를 작성한다.
이때 make_str에는 split함수에 따라, 앞의 sep은 보내고 난 뒤의 str포인터가 들어온다.char make_str(char *str, char *sep) { int str_len; int i; char *new_str; str_len = 0; while (*(str + str_len) && !is_sep(str[str_len], sep)) ++str_len; new_str = (char *)malloc(str_len * sizeof(char) + 1); if (new_str == 0) return (0); i = 0; while (i < str_len) { new_str[i] = str[i]; ++i; } new_str[i] = 0; return (new_str); }