[42Seoul] libft - String 관련 함수

skyju·2022년 4월 27일
0

libft

목록 보기
2/3

String 관련 함수

atoi

string -> int로 변환.
주석부분은 빼는 것이 나을 것 같다.. 원본함수와 작동이 다름
overflow를 원본함수와 완벽히 똑같이 처리해줄 거라면 더 복잡한 처리방식이 요구된다.

int	ft_isspace(char c)
{
	if (c == ' ' || c == '\t' || c == '\n'
		|| c == '\v' || c == '\r' || c == '\f')
		return (1);
	else
		return (0);
}

int	ft_atoi(const char *str)
{
	int		pos;
	int		flag;
	size_t	res;

	pos = 0;
	while (str[pos] != '\0' && ft_isspace(str[pos]))
		++pos;
	flag = 1;
	if (str[pos] == '-')
		flag = -1;
	if (str[pos] == '-' || str[pos] == '+')
		++pos;
	res = 0;
	while (str[pos] != '\0' && str[pos] >= '0' && str[pos] <= '9')
	{
		res *= 10;
		res += (str[pos] - '0');
		++pos;
	}
    /*
	if (res > 2147483647 && flag == 1)
		return (-1);
	if (res > 2147483648 && flag == -1)
		return (0);
    */
	return (res * flag);
}

itoa

int -> String으로 변환.
putnbr 재귀로 만들었던 것 활용해서 만들었음!

int	malloc_size_cal(long int nbr)
{
	int	cnt;

	cnt = 1;
	if (nbr < 0)
	{
		++cnt;
		nbr *= -1;
	}
	while (nbr >= 10)
	{
		nbr /= 10;
		++cnt;
	}
	return (cnt);
}

void	make_str(char *res, long int nbr, int i)
{
	if (nbr < 0)
	{
		*res = '-';
		nbr *= -1;
	}
	if (nbr / 10 != 0)
		make_str(res, nbr / 10, i - 1);
	else
	{
		*(res + i) = nbr + '0';
		return ;
	}
	make_str(res, nbr % 10, i);
}

char	*ft_itoa(int nbr)
{
	char	*res;
	int		malloc_size;

	malloc_size = malloc_size_cal(nbr);
	res = (char *)malloc(sizeof(char) * (malloc_size + 1));
	if (!res)
		return (NULL);
	make_str(res, nbr, malloc_size - 1);
	res[malloc_size] = '\0';
	return (res);
}

split

문자열 s를 구분자 c를 기준으로 나누어 문자열 배열로 return한다.
예전에 만들었던 것 돌려봤는데 count_words함수에서 할당 크기 계산에 문제가 있어서
count_words함수만 다시 만들었다..!

바뀐 핵심은 다음과 같음.
문자열 처음에 구분자가 나올 때 indexing을 잘 증가시켜주고
마지막으로 continue를 만나서 while문이 끝났을 때, 구분자가 아닌 끝글자가 남아있을 것을
대비하기 위해 if문 하나를 둔다.

int	is_sep(char s, char c)
{
	return (s == c);
}

int	count_words(char const *s, char c)
{
	int	i;
	int	words_num;

	i = 0;
	words_num = 0;
	if (!s[0])
		return (0);
	while (s[i] && is_sep(s[i], c))
		++i;
	while (s[i])
	{
		if (is_sep(s[i], c))
		{
			words_num++;
			while (s[i] && is_sep(s[i], c))
				++i;
			continue ;
		}
		++i;
	}
	if (s[i - 1] != c)
		words_num++;
	return (words_num);
}

char	*ft_make_str(char *str, char c)
{
	char	*res;
	int		res_len;
	int		i;

	res_len = 0;
	while (*(str + res_len) && !is_sep(str[res_len], c))
		++res_len;
	res = (char *)malloc(sizeof(char) * (res_len + 1));
	if (!res)
		return (NULL);
	i = 0;
	while (i < res_len)
	{
		res[i] = str[i];
		++i;
	}
	res[i] = '\0';
	return (res);
}

char	**ft_split(char const *s, char c)
{
	char	**res;
	int		i;
	int		res_i;

	if (s == NULL)
		return (NULL);
	res = (char **)malloc(sizeof(char *) * (count_words(s, c) + 1));
	if (!res)
		return (NULL);
	i = 0;
	res_i = 0;
	while (s[i])
	{
		while (s[i] && is_sep(s[i], c))
			++i;
		if (s[i] && !is_sep(s[i], c))
			res[res_i++] = ft_make_str((char *)(s + i), c);
		while (s[i] && !is_sep(s[i], c))
			++i;
	}
	res[res_i] = 0;
	return (res);
}

strdup

매개변수로 들어온 문자열 src를 동적할당하여 return해준다.

char	*ft_strdup(char *src)
{
	char	*str;
	int		i;

	i = 0;
	while (src[i])
		++i;
	str = (char *)malloc(sizeof(char) * (i + 1));
	if (!str)
		return (0);
	i = 0;
	while (src[i])
	{
		str[i] = src[i];
		++i;
	}
	str[i] = '\0';
	return (str);
}

strlcat

두문자열 dest와 src를 붙이는 함수. dest의 뒤에 src를 size만큼 붙인다.

size_t	ft_strlcat(char *dest, const char *src, size_t size)
{
	size_t	dest_length;
	size_t	src_length;
	size_t	i;

	dest_length = ft_strlen(dest);
	src_length = ft_strlen(src);
	i = 0;
	if (size < dest_length + 1)
		return (src_length + size);
	while (*(src + i) && dest_length + i + 1 < size)
	{
		*(dest + dest_length + i) = *(src + i);
		++i;
	}
	*(dest + dest_length + i) = '\0';
	return (src_length + dest_length);
}

strlcpy

src의 문자를 dest로 size만큼 복사한다.

size_t	ft_strlcpy(char *dest, const char *src, size_t size)
{
	size_t	i;
	size_t	src_length;

	i = 0;
	src_length = ft_strlen(src);
	while (*(src + i) && i + 1 < size)
	{
		*(dest + i) = *(src + i);
		++i;
	}
	if (size > 0)
		*(dest + i) = '\0';
	return (src_length);
}

strjoin

두 문자열 s1과 s2를 붙여서 하나의 문자열로 만들어준다.

char	*ft_strjoin(char const *s1, char const *s2)
{
	char	*res;
	int		s1_len;
	int		s2_len;

	if (!s1 && !s2)
		return (0);
	else if (!s1)
		return (ft_strdup((char *)s2));
	else if (!s2)
		return (ft_strdup((char *)s1));
	s1_len = ft_strlen((char *)s1);
	s2_len = ft_strlen((char *)s2);
	res = (char *)malloc(sizeof(char) * (s1_len + s2_len + 1));
	if (!res)
		return (NULL);
	ft_strlcpy(res, (char *)s1, s1_len + 1);
	ft_strlcat(res + s1_len, (char *)s2, s2_len + 1);
	return (res);
}

strchr

문자열 s에서 문자 c가 있는지 검사한다.
만약 있다면 그 위치의 포인터를 반환한다.

char	*ft_strchr(const char *s, int c)
{
	while (*s)
	{
		if (*s == (unsigned char)c)
			return ((char *)s);
		++s;
	}
	if (*s == (unsigned char)c)
		return ((char *)s);
	return (0);
}

strrchr

문자열 s에서 문자 c가 있는지 검사하는데,
뒤에서 부터 (reversing) 검사한다.
만약 있다면 그 위치의 포인터를 반환한다.

char	*ft_strrchr(const char *s, int c)
{
	int	s_len;

	s_len = ft_strlen((char *)s);
	while (s_len >= 0)
	{
		if (s[s_len] == (unsigned char)c)
			return ((char *)(s + s_len));
		--s_len;
	}
	return (NULL);
}

striteri

문자열 s의 크기만큼 반복하며 각 문자에 함수 f를 적용한다.

void	ft_striteri(char *s, void (*f)(unsigned int, char*))
{
	int	s_len;
	int	i;

	i = 0;
	if (!s || !f)
		return ;
	s_len = ft_strlen(s);
	while (i < s_len)
	{
		f(i, &s[i]);
		++i;
	}
}

strmapi

문자열 s의 크기만큼 반복하며 각 문자에 함수 f를 적용하여 만든 문자열을 반환한다.
그 문자열을 동적할당 되어있어야 한다.

char	*ft_strmapi(char const *s, char (*f)(unsigned int, char))
{
	char	*res;
	int		s_len;
	int		i;

	i = 0;
	if (!s || !f)
		return (0);
	s_len = ft_strlen((char *)s);
	res = (char *)malloc(sizeof(char) * (s_len + 1));
	if (!res)
		return (NULL);
	while (i < s_len)
	{
		res[i] = f(i, s[i]);
		++i;
	}
	res[i] = '\0';
	return (res);
}

strnstr

문자열 haystack에 needle이 있는지 len만큼 검사하며 찾는다.
만약 needle을 발견하면 needle이 처음 발견된 haystack의 포인터를 반환한다.

char	*ft_strnstr(const char *haystack, const char *needle, size_t len)
{
	size_t	i;

	i = 0;
	if (needle[0] == '\0')
		return ((char *)haystack);
	while (*haystack != '\0' && len > 0)
	{
		i = 0;
		while (*(haystack + i) == *(needle + i) && (i < len))
		{
			i++;
			if (*(needle + i) == '\0')
				return ((char *)haystack);
		}
		len--;
		haystack++;
	}
	return (0);
}

strtrim

문자열 s1의 앞과 뒤에 set에 포함된 문자가 있다면 제거한 후 만들어진 문자열을 반환한다.
특정 문자가 문자열에 있는지 검사해주는 strchr 함수를 활용한다.
앞에 제거해야할 indexing -> cal_start로 계산
뒤에 제거해야할 indexing -> cal_end로 계산

int	ft_cal_start(char const *s, char const *set, size_t len)
{
	size_t	i;

	i = 0;
	while (i < len)
	{
		if (ft_strchr(set, s[i]) == 0)
			break ;
		++i;
	}
	return (i);
}

int	ft_cal_end(char const *s, char const *set, size_t len)
{
	size_t	i;

	i = 0;
	while (i < len)
	{
		if (ft_strchr(set, s[len - i - 1]) == 0)
			break ;
		++i;
	}
	return (len - i);
}

char	*ft_strtrim(char const *s1, char const *set)
{
	char	*res;
	int		start;
	int		end;
	size_t	s1_len;

	if (!s1)
		return (NULL);
	if (!set)
		return (ft_strdup((char *)s1));
	s1_len = (size_t)ft_strlen((char *)s1);
	start = ft_cal_start(s1, set, s1_len);
	end = ft_cal_end(s1, set, s1_len);
	if (start >= end)
		return (ft_strdup(""));
	res = (char *)malloc(sizeof(char) * (end - start + 1));
	if (!res)
		return (NULL);
	ft_strlcpy(res, ((char *)s1 + start), end - start + 1);
	return (res);
}

substr

원본 문자열 s에서 start포인트에서 len크기 만큼 떼어서 하위 문자열을 만들어주는 함수.

char	*ft_substr(char const *s, unsigned int start, size_t len)
{
	char	*res;
	size_t	len_tmp;

	if (s == NULL)
		return (NULL);
	if ((unsigned int)ft_strlen(s) < start)
		return (ft_strdup(""));
	len_tmp = ft_strlen(s + start);
	if (len_tmp < len)
		len = len_tmp;
	res = (char *)malloc(sizeof(char) * (len + 1));
	if (!res)
		return (NULL);
	ft_strlcpy(res, s + start, len + 1);
	return (res);
}
profile
https://github.com/skyju

0개의 댓글