void *ft_memset(void *b, int c, size_t len)
{
size_t i;
unsigned char *tmp_ptr;
tmp_ptr = (unsigned char *)b;
i = 0;
while (len--)
tmp_ptr[i++] = (unsigned char)c;
return (b);
}
void ft_bzero(void *s, size_t n)
{
char *tmp_ptr;
size_t i;
tmp_ptr = (char *)s;
i = 0;
while (n--)
{
tmp_ptr[i] = '\0';
i++;
}
}
void *ft_memcpy(void *dst, const void *src, size_t n)
{
size_t i;
unsigned char *dst_ptr;
unsigned char *src_ptr;
if (dst == 0 && src == 0)
return (0);
dst_ptr = (unsigned char *)dst;
src_ptr = (unsigned char *)src;
i = 0;
while (i < n)
{
dst_ptr[i] = src_ptr[i];
i++;
}
return (dst);
}
[Point : NULL 반환]
if (dst == 0 && src == 0) 이 조건이 아니라 if (dst == 0 || src == 0) 일때 NULL을 반환해야하는게 아닐까? 하는 의문이 들 수 있음.하지만 memcpy의 정의상 NULL을 반환하는 특이 케이스가 명시되어 있지 않다. 따라서 위의 조건문은 dst가 NULL일 수 밖에 없는 조건일때 NULl을 반환한다고 보는것이 적절하다.
void *ft_memccpy(void *dst, const void *src, int c, size_t n)
{
size_t i;
unsigned char *dst_ptr;
unsigned char *src_ptr;
dst_ptr = (unsigned char *)dst;
src_ptr = (unsigned char *)src;
i = 0;
while (i < n)
{
dst_ptr[i] = src_ptr[i];
if (src_ptr[i] == (unsigned char)c)
return (dst + i + 1);
i++;
}
return (0);
}
void *ft_memmove(void *dst, const void *src, size_t len)
{
size_t i;
unsigned char *dst_ptr;
unsigned char *src_ptr;
if (dst == src || len == 0)
return (dst);
dst_ptr = (unsigned char *)dst;
src_ptr = (unsigned char *)src;
if (dst < src)
ft_memcpy(dst_ptr, src_ptr, len);
else
{
i = 0;
while (len - i > 0)
{
dst_ptr[len - i - 1] = src_ptr[len - i - 1];
i++;
}
}
return (dst);
}
[Point : stack 영역을 활용한 swap]
unsigned char *tmp[len]을 선언하고 memcpy를 이용해서 더 짧게 코드를 짤 수 있다. 하지만 stack 영역은 8mb로 제한되어있는데, len에 8mb보다 큰 메모리 영역이 들어온다면? 오류가 나타날 것이다.
[Point : src > dst 인 경우]
stack 영역을 따로 활용하기 어렵기 때문에, 결국 주소값의 대소를 비교하여 copy작업을 분리해줘야한다. dst > src 인 경우는 memcpy를 활용하여 손쉽게 처리할 수 있지만, 그 반대의 경우는 그렇지 않다. 이 경우에는 src의 제일 뒤에서부터 dst의 제일 뒤로 붙이면 문제 없이 해결된다.
void *ft_memchr(const void *s, int c, size_t n)
{
unsigned char *ptr;
ptr = (unsigned char *)s;
while (n--)
{
if (*ptr == (unsigned char)c)
return (ptr);
ptr++;
}
return (0);
}
int ft_memcmp(const void *s1, const void *s2, size_t n)
{
unsigned char *ptr1;
unsigned char *ptr2;
if (n == 0)
return (0);
ptr1 = (unsigned char *)s1;
ptr2 = (unsigned char *)s2;
while (n--)
{
if (*ptr1 != *ptr2)
return ((int)(*ptr1 - *ptr2));
ptr1++;
ptr2++;
}
return (0);
}
size_t ft_strlen(const char *str)
{
size_t i;
i = 0;
while (str[i])
i++;
return (i);
}
size_t ft_strlcpy(char *dst, const char *src, size_t dstsize)
{
size_t len;
size_t i;
if (!src)
return (0);
len = ft_strlen(src);
i = 0;
if (dstsize == 0)
return (len);
while (src[i] && (i + 1) < dstsize)
{
dst[i] = src[i];
i++;
}
dst[i] = '\0';
return (len);
}
[Point : copy의 중단]
함수의 설명만 보면 i + i < dstsize 조건동안 copy만 하면 될것 같지만, 문자열을 복사하는 것이기 때문에 문자열의 종료(*src == '\0')가 나타나면 copy를 중단한다.
size_t ft_strlcat(char *dst, const char *src, size_t dstsize)
{
size_t dst_len;
size_t src_len;
size_t i;
dst_len = ft_strlen(dst);
src_len = ft_strlen(src);
i = 0;
if (dst_len >= dstsize)
return (dstsize + src_len);
while (src[i] && i + 1 + dst_len < dstsize)
{
dst[dst_len + i] = src[i];
i++;
}
dst[dst_len + i] = '\0';
return (dst_len + src_len);
}
char *ft_strchr(const char *s, int c)
{
unsigned char data;
unsigned char *str;
str = (unsigned char *)s;
data = (unsigned char)c;
while (*str)
{
if (*str == data)
return ((char *)str);
str++;
}
if (data == '\0')
return ((char *)str);
return (NULL);
}
char *ft_strrchr(const char *s, int c)
{
int i;
unsigned char data;
unsigned char *str;
data = (unsigned char)c;
str = (unsigned char *)s;
i = ft_strlen(s);
if (data == '\0')
return ((char *)(str + i));
while (i >= 0)
{
if (str[i] == data)
return ((char *)(str + i));
i--;
}
return (0);
}
char *ft_strnstr(const char *haystack, const char *needle, size_t len)
{
size_t i;
size_t j;
if (*needle == 0)
return ((char *)haystack);
i = 0;
while (haystack[i] && i < len)
{
j = 0;
while (haystack[i + j] && i + j < len && haystack[i + j] == needle[j])
j++;
if (needle[j] == '\0')
return ((char *)(haystack + i));
i++;
}
return (NULL);
}
int ft_strncmp(const char *s1, const char *s2, size_t n)
{
size_t i;
if (n == 0)
return (0);
i = 0;
while (s1[i] && s2[i] && (i + 1) < n &&
(unsigned char)s1[i] == (unsigned char)s2[i])
i++;
return ((unsigned char)s1[i] - (unsigned char)s2[i]);
}
static int judge_return(long res)
{
if (res > 2147483647)
return (-1);
if (res < -2147483648)
return (0);
return (1);
}
int ft_atoi(const char *str)
{
size_t i;
int sign;
long res;
i = 0;
while ((str[i] >= 9 && str[i] <= 13) || str[i] == 32)
i++;
sign = 1;
if (str[i] == '-' || str[i] == '+')
{
if (str[i] == '-')
sign = -1;
i++;
}
if (!ft_isdigit(str[i]))
return (0);
res = 0;
while (ft_isdigit(str[i]))
{
res = res * 10 + (sign * (str[i] - '0'));
if (judge_return(res) <= 0)
return (judge_return(res));
i++;
}
return ((int)res);
}
[Point : long 형으로 결과값 저장]
str에 int형을 넘어서는 숫자가 들어올경우 이를 판단하기 위해서 long 형 데이터에 결과값을 계속 갱신하면서 judge_return 함수로 판단하기 위함.
char *ft_strdup(const char *s1)
{
size_t len;
size_t i;
char *new_ptr;
len = 0;
while (s1[len])
len++;
if (!(new_ptr = (char *)malloc((len + 1) * sizeof(char))))
return (NULL);
i = 0;
while (i < len)
{
new_ptr[i] = s1[i];
i++;
}
new_ptr[i] = '\0';
return (new_ptr);
}
void *ft_calloc(size_t count, size_t size)
{
char *new_ptr;
size_t i;
if (!(new_ptr = (char *)malloc(size * count)))
return (NULL);
i = 0;
while (i < size * count)
{
new_ptr[i] = '\0';
i++;
}
return ((void *)new_ptr);
}
이하 isapha등은 생략한다.