[libft] Part2

timothy jeong·2021년 5월 10일
0

libft

목록 보기
2/3
post-thumbnail

libft part2

[ft_substr]

  • 원형 : char *ft_substr(char const *s, unsigned int start, size_t len)
  • 정의 : 문자열 s에 대해 start 에서부터 len 범위까지의 하위 문자열을 생성하여 반환하는 함수, 만약 start가 s의 길이를 넘어서서 하위 문자열을 생성할 수 없다면 빈 문자열을 반환해야한다.
  • 반환 값 :
    (1) 하위 문자열을 만들 수 있다면 생성된 하위 문자열 포인터
    (2) 만들 수 없다면 빈 문자열
char	*ft_substr(char const *s, unsigned int start, size_t len)
{
	size_t	i;
	size_t	str_len;
	char	*substr;

	if (s == 0)
		return (NULL);
	str_len = ft_strlen(s);
	if (start >= str_len)
		return (ft_strdup(""));
	if (len >= str_len - start)
		len = str_len - start;
	if (!(substr = (char *)malloc(len * sizeof(char) + 1)))
		return (NULL);
	i = 0;
	while (s[start + i] && i < len)
	{
		substr[i] = s[start + i];
		i++;
	}
	substr[i] = '\0';
	return (substr);
}

[Point : if (len >= str_len - start) ?]
이 부분이 없어도 통과는 될 것이다. 하지만 필요한 크기보다 더 많은 크기의 메모리를 할당하고 싶지 않다면 필요하다.
예를 들어 주어진 문자열 s의 길이가 10이고, start가 5이지만, len이 100으로 주어진다면 101크기를 malloc하기 보다는 5를 malloc 하기 위한 부분이다.

[ft_strjoin]

  • 원형 : char *ft_strjoin(char const s1, char const s2)
  • 정의 : s1과 s2를 concat한 새로운 문자열을 만들어라.
  • 반환 값 : 만들어진 포인터
char	*ft_strjoin(char const *s1, char const *s2)
{
	size_t	s1_len;
	size_t	s2_len;
	char	*concat;

	if (!s1 || !s2)
		return (NULL);
	s1_len = ft_strlen(s1);
	s2_len = ft_strlen(s2);
	if (!(concat = (char *)malloc((s1_len + s2_len) * sizeof(char) + 1)))
		return (NULL);
	ft_bzero(concat, (s1_len + s2_len + 1));
	ft_strlcpy(concat, (char *)s1, s1_len + 1);
	ft_strlcpy(&concat[s1_len], (char *)s2, s2_len + 1);
	return (concat);
}

[ft_strtrim]

  • 원형 : char *ft_strtrim(char const s1, char const set)
  • 정의 : 문자열 s1에서 앞 뒤에서 set의 각 문자와 일치하는 부분을 모두 정리(trim)하고, 정리된 문자열을 반환하라.
  • 반환 값 : 만들어진 포인터
char	*ft_strtrim(char const *s1, char const *set)
{
	size_t	front;
	size_t	back;
	char	*tmp_ptr;
	char	*trimed_str;

	if (!s1 || !set)
		return (NULL);
	front = 0;
	back = 0;
	tmp_ptr = (char *)s1;
	while (s1[front] && ft_strchr(set, s1[front]))
		front++;
	back = ft_strlen(tmp_ptr + front);
	if (back > 0)
		while (tmp_ptr[back + front - 1] &&
				ft_strchr(set, tmp_ptr[back + front - 1]))
			back--;
	if (!(trimed_str = (char *)malloc(back * sizeof(char) + 1)))
		return (NULL);
	ft_strlcpy(trimed_str, tmp_ptr + front, back + 1);
	trimed_str[back] = '\0';
	return (trimed_str);
}

[ft_split]

  • 원형 : char **ft_split(char const *s, char c)
  • 정의 : 문자열 s1에 대해 문자 c가 나올때마다 문자열을 잘라서 새로운 2차원 포인터 각 계층에 할당하라, 2차원 포인터 마지막에는 NULL 포인터를 가리키고 있어야한다.
  • 반환 값 : 만들어진 2차원 포인터
static char		**ft_allfree(char **res)
{
	size_t	i;

	i = 0;
	while (res[i])
	{
		free(res[i]);
		i++;
	}
	free(res);
	return (NULL);
}

static size_t	getsize(char const *s, char c)
{
	size_t	i;
	size_t	size;

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

static size_t	ft_getlen(char *str, char c)
{
	size_t i;

	i = 0;
	while (str[i])
	{
		if (str[i] == c)
			return (i);
		i++;
	}
	return (i);
}

static char		**ft_result(char **res, char const *s, size_t size, char c)
{
	char	*str;
	size_t	i;
	size_t	next_len;

	i = 0;
	str = (char *)s;
	next_len = 0;
	while (i < size)
	{
		while (*str == c)
			str++;
		next_len = ft_getlen(str, c);
		if (!(res[i] = (char *)malloc(sizeof(char) * (next_len + 1))))
			return (ft_allfree(res));
		ft_strlcpy(res[i], str, next_len + 1);
		str += next_len;
		i++;
	}
	res[i] = NULL;
	return (res);
}

char			**ft_split(char const *s, char c)
{
	char	**res;
	size_t	size;

	if (!s)
		return (NULL);
	size = getsize(s, c);
	if (!(res = (char **)malloc(sizeof(char *) * (size + 1))))
		return (NULL);
	return (ft_result(res, s, size, c));
}

[ft_itoa]

  • 원형 : char *ft_itoa(int n)
  • 정의 : 주어진 int n을 문자열 형태로 변환하여 반환하라
  • 반환 값 : 포인터 시작 주소
static int	ft_digit(int n)
{
	int digit;

	digit = 1;
	while (n /= 10)
		digit++;
	return (digit);
}

static void	ft_itoa_insert(int n, char *converted, int size)
{
	int limit;
	int sign;

	limit = 0;
	sign = 1;
	converted[size] = '\0';
	if (n < 0)
	{
		converted[0] = '-';
		limit = 1;
		sign = -1;
	}
	while (size-- > limit)
	{
		converted[size] = (((n % 10) * sign) + '0');
		n /= 10;
	}
}

char		*ft_itoa(int n)
{
	char	*converted;
	int		size;

	size = n < 0 ? ft_digit(n) + 1 : ft_digit(n);
	converted = (char *)malloc(size * sizeof(char) + 1);
	if (!converted)
		return (NULL);
	else
		ft_itoa_insert(n, converted, size);
	return (converted);
}

[ft_strmapi]

  • 원형 : char *ft_strmapi(char const s, char (f)(unsigned int, char))
  • 정의 : 문자열 s의 각 문자에 f 함수를 연속적으로 적용하고, 그 적용 결과물을 반환하라.
  • 반환 값 : 포인터 시작 주소
char	*ft_strmapi(char const *s, char (*f)(unsigned int, char))
{
	unsigned int	i;
	size_t			len;
	char			*tmp;

	if (!s || !f)
		return (NULL);
	len = ft_strlen((char *)s);
	tmp = (char *)ft_calloc(len + 1, sizeof(char));
	if (!tmp)
		return (NULL);
	i = 0;
	while (i < len)
	{
		tmp[i] = f(i, s[i]);
		i++;
	}
	return (tmp);
}

이하 file descriptor 에 문자, 문자열, 숫자, 개행등을 작성하는 함수는 생략한다.

profile
개발자

0개의 댓글