[Libft] Part 1

dev2l0per·2020년 10월 11일
1

42seoul

목록 보기
1/1

42cursus 과정의 첫 과제인 Libft의 Part 1 부분을 정리하고자 한다.

1. ft_memset

void                            *ft_memset(void *b, int c, size_t len)
{
        unsigned char   *new_b;
        unsigned char   src;
        size_t                  i;

        new_b = (unsigned char *)b;
        src = (unsigned char)c;
        i = 0;
        while (i < len)
        {
                *new_b++ = src;
                i++;
        }
        return (b);
}

memset 함수는 어떤 메모리의 시작점부터 연속된 범위를 어떤 값으로(바이트 단위) 모두 지정하고 싶을 때 사용하는 함수이다.

2. ft_bzero

void                            ft_bzero(void *s, size_t n)
{
        unsigned char   *dst;
        size_t                  i;

        dst = (unsigned char *)s;
        i = 0;
        while (i < n)
        {
                *dst++ = 0;
                i++;
        }
}

memset과 유사하게 메모리의 시작점부터 연속된 범위를 0으로 초기화하는 함수이다.

  • 비표준 함수 이기 때문에 memset을 사용하기를 추천한다.

3. ft_memcpy

void                            *ft_memcpy(void *dst, const void *src, size_t n)
{
        unsigned char   *new_dst;
        unsigned char   *new_src;
        size_t                  i;

        if (!dst && !src)
                return (0);
        new_dst = (unsigned char *)dst;
        new_src = (unsigned char *)src;
        i = 0;
        while (i < n)
        {
                *new_dst++ = *new_src++;
                i++;
        }
        return (dst);
}

src가 가르키는 memory 부터 n 바이트 만큼 dst가 가르키는 메모리에 복사하는 함수이다.

  • null 문자를 검사하지 않고 n 바이트 만큼 무조건 적으로 복사하게 된다.
  • overlap 문제가 발생할 수 있기 때문에 memmove 함수를 사용하는 것을 추천한다.
    memcpy vs memmove

4. ft_memccpy

void                            *ft_memccpy(void *dst, const void *src, int c, size_t n)
{
        unsigned char   *new_dst;
        unsigned char   *new_src;
        unsigned char   find;
        size_t                  i;

        new_dst = (unsigned char *)dst;
        new_src = (unsigned char *)src;
        find = (unsigned char)c;
        i = 0;
        while (i < n)
        {
                *new_dst = *new_src;
                if (*new_src == find)
                        return (dst + (i + 1));
                new_dst++;
                new_src++;
                i++;
        }
        return (0);
}

src 데이터에서 n바이트의 데이터를 dest에 복제할 때에 src 데이터에서 문자 c를 만나면 c까지 복제하고 복제를 중단합니다.
복제된 dest변수에서 복제가 끝난 다음 번지를 return합니다.
만약 문자 c를 만나지 않았다면, n바이트를 복제하고 NULL을 return하는 함수이다.

5. ft_memmove

void                            *ft_memmove(void *dst, const void *src, size_t len)
{
        unsigned char   *new_dst;
        unsigned char   *new_src;
        size_t                  i;

        if (dst == src || len == 0)
                return (dst);
        new_dst = (unsigned char *)dst;
        new_src = (unsigned char *)src;
        i = 0;
        if (dst < src)
                while (i++ < len)
                        *new_dst++ = *new_src++;
        else
        {
                new_dst = new_dst + len - 1;
                new_src = new_src + len - 1;
                while (i++ < len)
                        *new_dst-- = *new_src--;
        }
        return (dst);
}

src 메모리 영역에서 dest 메모리 영역으로 n byte 만큼 복사합니다.
src 배열은 src와 dest 의 메모리 영역과 겹치지 않는 메모리 영역부터 먼저 복사하는 함수이다.

memmove 사용법 및 구현

  • overlap 의 해결 방안
    - 뒤에서 부터 한 바이트씩 복사한다.

6. ft_memchr

void            *ft_memchr(const void *s, int c, size_t n)
{
        size_t  i;

        i = 0;
        while (i++ < n)
        {
                if (*(unsigned char *)s == (unsigned char)c)
                        return ((void *)s);
                s++;
        }
        return (0);
}

s가 가르키는 memory에서 n 바이트 중 c가 나타내는 문자를 찾아 주소를 반환하는 함수이다.

7. ft_memcmp

int                     ft_memcmp(const void *s1, const void *s2, size_t n)
{
        size_t  i;

        i = 0;
        while (i++ < n)
        {
                if (*(unsigned char *)s1 != *(unsigned char *)s2)
                        return (*(unsigned char *)s1 - *(unsigned char *)s2);
                s1++;
                s2++;
        }
        return (0);
}

s1이 가르키는 주소에서 n 바이트의 데이터와 s2가 가르키는 주소에서 n 바이트의 데이터를 비교하여 같으면 0을 반환하는 함수이다.

  • 오버플로우 처리가 가능한가 ?
    memcmp overflow
    무조건 n 바이트만큼 비교하기 때문에 널문자를 지나 쓰레기 값끼리 비교할 수도 있는 문제점
    n 바이트의 크기에 주의하자.

8. ft_strlen

size_t          ft_strlen(const char *s)
{
        size_t  len;

        len = 0;
        while (s[len])
                len++;
        return (len);
}

문자열 s를 인자로 받아 길이를 반환해 주는 함수

9. ft_strlcpy

size_t          ft_strlcpy(char *dst, const char *src, size_t dstsize)
{
        size_t  src_len;
        size_t  i;

        if (dst == 0 || src == 0)
                return (0);
        src_len = ft_strlen(src);
        i = 0;
        if (dstsize > 0)
        {
                while (src[i] != '\0' && i < dstsize - 1)
                {
                        dst[i] = src[i];
                        i++;
                }
                dst[i] = '\0';
        }
        return (src_len);
}

참고자료

10. ft_strlcat

size_t          ft_strlcat(char *dst, const char *src, size_t dstsize)
{
        size_t  dst_len;
        size_t  src_len;
        size_t  i;
        size_t  dst_len_tmp;

        dst_len = 0;
        src_len = ft_strlen(src);
        if (dstsize == 0)
                return (src_len);
        while (dst[dst_len] != '\0' && dst_len < dstsize)
                dst_len++;
        dst_len_tmp = dst_len;
        i = 0;
        if (dst_len < dstsize)
        {
                while (dst_len < (dstsize - 1) && src[i])
                        dst[dst_len++] = src[i++];
                dst[dst_len] = '\0';
        }
        if (dstsize < dst_len_tmp)
                return (dstsize + src_len);
        return (dst_len_tmp + src_len);
}

참고자료 1
참고자료 2

11. ft_strchr

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

12. ft_strrchr

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

        str = NULL;
        while (*s != '\0')
        {
                if (*s == (char)c)
                        str = (char *)s;
                s++;
        }
        if ((char)c == '\0')
                return ((char *)s);
        return (str);
}

13. ft_strnstr

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

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

14. ft_strncmp

int                     ft_strncmp(const char *s1, const char *s2, size_t n)
{
        size_t  i;

        if (n == 0)
                return (0);
        i = 0;
        while (i < n - 1 && s1[i] == s2[i] && s1[i] != '\0' && s2[i] != '\0')
                i++;
        return ((unsigned char)s1[i] - (unsigned char)s2[i]);
}

15. ft_atoi

int                                     ft_atoi(const char *str)
{
        long long int   res;
        long long int   sign;

        res = 0;
        sign = 1;
        while (*str && (*str == ' ' || (*str >= 9 && *str <= 13)))
                str++;
        if (*str == '-' || *str == '+')
        {
                if (*str == '-')
                        sign = sign * -1;
                str++;
        }
        while (*str >= '0' && *str <= '9')
        {
                res = res * 10 + *str - '0';
                if (res > 2147483647 && sign == 1)
                        return (-1);
                if (res > 2147483648 && sign == -1)
                        return (0);
                str++;
        }
        return (sign * res);
}

16. ft_isalpha

int             ft_isalpha(int c)
{
        return ((c >= 65 && c <= 90) || (c >= 97 && c <= 122));
}

17. ft_isdigit

int             ft_isdigit(int c)
{
        return (c >= '0' && c <= '9');
}

18. ft_isalnum

int             ft_isalnum(int c)
{
        return (ft_isalpha(c) || ft_isdigit(c));
}

19. ft_isascii

int             ft_isascii(int c)
{
        return (c >= 0 && c <= 127);
}

20. ft_isprint

int             ft_isprint(int c)
{
        return (c >= 32 && c <= 126);
}

21. ft_toupper

int             ft_toupper(int c)
{
        if (c >= 97 && c <= 122)
                c = c - 32;
        return (c);
}

22. ft_tolower

int             ft_tolower(int c)
{
        if (c >= 65 && c <= 90)
                c = c + 32;
        return (c);
}

23. ft_calloc

void            *ft_calloc(size_t count, size_t size)
{
        void    *memory;

        if (!(memory = malloc(count * size)))
                return (0);
        ft_bzero(memory, count * size);
        return (memory);
}

24. ft_strdup

char            *ft_strdup(const char *s1)
{
        size_t  len;
        size_t  i;
        char    *str;

        len = ft_strlen(s1);
        if (!(str = (char *)malloc(sizeof(char) * (len + 1))))
                return (0);
        i = 0;
        while (i < len)
        {
                str[i] = s1[i];
                i++;
        }
        str[i] = '\0';
        return (str);
}
profile
42Seoul Cadet

1개의 댓글

comment-user-thumbnail
2020년 10월 17일

너무 좋아용

답글 달기