[libft] 나만의 C라이브러리 만들기 Part 2

leocodms·2020년 12월 27일
0

42seoul

목록 보기
5/10

1.ft_substr

#include "libft.h"

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

	if (s == NULL)
		return (NULL);
	if (ft_strlen(s) < start)
		return (ft_strdup(""));
	if (!(str = (char *)malloc(sizeof(char) * (len + 1))))
		return (NULL);
	ft_strlcpy(str, s + start, len + 1);
	return (str);
}
  • 기능 : 문자열 s의 하위 문자열을 반환. 인덱스 start에서 시작해서 최대 길이 len이다.
  • return : s의 하위 문자열. 할당 실패시 null.
  • 문자열을 자를때 기본 함수로 사용한다.
  • 풀이 : s가 빈 문자열이면 null 반환. 시작 인덱스보다 문자열의 길이가 작으면 아무것도 없는 문자열 반환. ft_strlcpy를 사용해서 복사.
  • 해당 문제를 통해서 strlcpy가 어느 경우에 사용하는지 이해함.

2.ft_strjoin

#include "libft.h"

char		*ft_strjoin(char const *s1, char const *s2)
{
	char	*ptr;
	int		len;
	int		i;

	if (s1 == NULL && s2 == NULL)
		return (NULL);
	else if (!(s1) || !(s2))
		return (!(s1) ? ft_strdup(s2) : ft_strdup(s1));
	len = ft_strlen(s1) + ft_strlen(s2);
	if (!(ptr = (char *)malloc(sizeof(char) * (len + 1))))
		return (NULL);
	i = 0;
	while (*s1 != 0)
		ptr[i++] = *s1++;
	while (*s2 != 0)
		ptr[i++] = *s2++;
	ptr[i] = 0;
    return (ptr)
  }
  • 기능 : 문자열 s1에 s2를 붙인다.
  • return : s1+s2를 한 새로운 문자열. 할당 실패시 null반환.
  • 풀이 : s1과 s2 모두 Null이면 null반환. 둘 중 한 문자열만 null이라면, null아닌 문자열을 복사해서 반환. s1 + s2의 길이를 구해서 반복문을 돌면서 새로운 문자열 생성.

3.ft_strtrim

#include "libft.h"

size_t		ft_start(char const *s1, char const *set, size_t slen)
{
	size_t	i;

	i = 0;
	while (i < slen && ft_strchr(set, s1[i]))
		i++;
	return (i);
}

size_t		ft_end(char const *s1, char const *set, size_t slen)
{
	size_t	i;

	i = 0;
	while (i < slen && ft_strchr(set, s1[slen - i - 1]))
		i++;
	return (slen - i);
}

char		*ft_strtrim(char const *s1, char const *set)
{
	char	*str;
	size_t	slen;
	size_t	start;
	size_t	end;
	size_t	i;

	if (s1 == 0)
		return (0);
	if (set == 0)
		return (ft_strdup(s1));
	i = 0;
	slen = ft_strlen(s1);
	start = ft_start(s1, set, slen);
	end = ft_end(s1, set, slen);
	if (start >= end)
		return (ft_strdup(""));
	if (!(str = (char *)malloc(sizeof(char) * (end - start - 1))))
		return (0);
	ft_strlcpy(str, s1 + start, end - start + 1);
	return (str);
}
  • 기능 : malloc을 할당하고 문자열의 처음과 끝에서 'set'에 지정된 문자가 제거된 문자열 's1'의 사본을 반환.

  • return : 문자가 제거된 문자열. 할당 실패시 NULL.

  • 예제 :
    s1 = "abc123cba" set = "abc" --> "123"
    s1 = "abc123c4ab" set = "abc" --> "123c4"

  • 풀이 : 문자열의 시작, 끝에서 부터 시작하여 ft_strchr로 set의 문자열에 해당 문자가 있는지 확인. 있다면 다음으로 넘어가고 없다면 인덱스 반환.
    그러면 반환된 인덱스는 각각 시작부분에서 set의 문자가 제거된 부분의 첫 위치, 끝 부분에서 시작하여 set의 문자가 제거된 부분의 첫 위치이다.
    해당 인덱스를 시작과 끝으로 해서 ft_strlcpy를 사용해서 메모리에 복사한다.

4.ft_split

#include "libft.h"

size_t		get_count(const char *s, char c)
{
	size_t	cnt;
	size_t	i;
	int		flag;

	i = 0;
	cnt = 0;
	flag = 0;
	while (s[i])
	{
		if (s[i] == c && s[i])
			flag = 0;
		else if (!flag && s[i] != c && s[i])
		{
			cnt++;
			flag = 1;
		}
		i++;
	}
	return (cnt);
}

void		copy(char *dst, char const *src, size_t start, size_t end)
{
	size_t	i;

	i = 0;
	while (start < end)
		dst[i++] = src[start++];
	dst[i] = 0;
}

void		split(char const *s, char c, char **str)
{
	size_t	start;
	size_t	i;
	size_t	j;

	start = 0;
	i = 0;
	j = 0;
	while (s[i])
	{
		if (s[i] != c && s[i])
		{
			start = i;
			while (s[i] != c && s[i])
				i++;
			if (!(str[j] = (char *)malloc(sizeof(char) * (i - start + 1))))
				return ;
			copy(str[j], s, start, i);
			j++;
		}
		else if (s[i])
			i++;
	}
}

char		**ft_split(char const *s, char c)
{
	char	**str;
	size_t	n;

	if (s == 0)
		return (NULL);
	n = get_count(s, c);
	if (!(str = (char **)malloc(sizeof(char *) * (n + 1))))
		return (NULL);
	str[n] = 0;
	if (n == 0)
		return (str);
	split(s, c, str);
	return (str);
}
  • 문자열 s를 char c를 기준으로 자른 후, 각 문자열들을 문자열의 배열에 담아서 반환한다.
  • return : 분할 결과를 담은 이차원 배열. 할당이 실패하면 null반환.
  • 풀이 :
    문자열 s가 c를 기준으로 몇개의 문자열로 나뉘는지 개수를 센다. 분할되는 문자열 개수 만큼 char *형 배열(str)을 할당한다. 실패하면 null 반환. str에 분할 된 문자열을 저장한다. split함수에서 s를 탐색하며 c앞의 문자열의 시작과 끝의 인덱스를 저장해서 해당 인덱스로 접근하여 복사한다.

5.ft_itoa

#include "libft.h"

size_t			nlen(long long n)
{
	size_t		i;

	i = 0;
	if (n == 0)
		return (1);
	else if (n < 0)
		n *= -1;
	while (n > 0)
	{
		n /= 10;
		i++;
	}
	return (i);
}

void			do_itoa(long long temp, char *str, size_t len)
{
	str[len] = 0;
	if (temp == 0)
	{
		str[--len] = '0';
		return ;
	}
	while (temp > 0)
	{
		str[--len] = (temp % 10) + '0';
		temp /= 10;
	}
}

char			*ft_itoa(int n)
{
	char		*str;
	size_t		len;
	long long	temp;

	len = nlen(n);
	temp = n;
	if (n < 0)
	{
		temp *= -1;
		len++;
	}
	if (!(str = (char *)malloc(sizeof(char) * (len + 1))))
		return (0);
	if (n < 0)
		str[0] = '-';
	do_itoa(temp, str, len);
	return (str);
}
  • 기능 : 숫자를 문자열로 반환한다. 음수 처리 당연함.
  • 반환 : 문자열
  • 풀이 : int n의 자릿수를 구한다(nlen 함수). n을 long long temp변수에 저장한다. n음수이면, temp도 음수로 변형하고, 길이도 하나 증가 해준다('-'기호 자리). 문자열을 길이+1(null문자)크기로 할당한다. 음수라면, 문자열의 맨앞에 음수 기호를 넣어준다. do_itoa함수에서 일의 자리부터 하나씩 문자열에 넣어준다.

6.ft_strmapi

#include "libft.h"

char		*ft_strmapi(char const *s, char (*f)(unsigned int, char))
{
	size_t	len;
	size_t	i;
	char	*str;

	i = 0;
	if (s == 0)
		return (0);
	len = ft_strlen(s);
	if (!(str = (char *)malloc(sizeof(char) * (len + 1))))
		return (0);
	while (i < len)
	{
		str[i] = f(i, s[i]);
		i++;
	}
	str[i] = 0;
	return (str);
}
  • 기능 : 함수 포인터로 들어온 함수를 문자열에 적용한다.
  • return : 함수가 적용된 문자로 생성 된 새로운 문자열. 할당 실패하면 null 반환.
  • 풀이 :
    문자열의 문자 하나하나 함수를 적용해야하기 때문에 문자열의 길이를 먼저 구하고, 그 길이만큼 반복문을 돌면서 함수를 적용한 문자열을 만들어 나간다.

7.ft_putchar_fd

#include "libft.h"

void	ft_putchar_fd(char c, int fd)
{
	if (fd < 0)
		return ;
	write(fd, &c, 1);
}
  • 기능 : 문자 c를 fd파일에 출력한다.
  • return : void
  • fd가 음수이면 유효하지 않은 파일 디스크립터 이므로 종료.

8.ft_putstr_fd

#include "libft.h"

void		ft_putstr_fd(char *s, int fd)
{
	size_t	i;

	i = 0;
	if (fd < 0)
		return ;
	while (s[i])
	{
		write(fd, &s[i], 1);
		i++;
	}
}
  • 기능 : 문자열을 fd 파일에 출력

9.ft_putendl_fd

#include "libft.h"

void		ft_putendl_fd(char *s, int fd)
{
	if (fd < 0)
		return ;
	write(fd, s, ft_strlen(s));
	write(fd, "\n", 1);
}
  • 기능 : ft_putstr_fd와 동일, 마지막에 개행 추가.

10.ft_putnbr_fd

#include "libft.h"

void		ft_putnbr_fd(int n, int fd)
{
	if (fd < 0)
		return ;
	if (n == -2147483648)
	{
		ft_putstr_fd("-2147483648", fd);
		return ;
	}
	if (n < 0)
	{
		ft_putchar_fd('-', fd);
		n *= -1;
	}
	if (n >= 10)
	{
		ft_putnbr_fd(n / 10, fd);
		ft_putnbr_fd(n % 10, fd);
	}
	if (n < 10)
		ft_putchar_fd(n + '0', fd);
}
  • 기능 : 정수를 파일 fd에 출력한다.
  • 가장 작은 정수는 수동으로 출력한다. 재귀함수를 사용해보았다.
profile
Backend Developer

0개의 댓글