libft part2
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 하기 위한 부분이다.
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);
}
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);
}
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));
}
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);
}
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 에 문자, 문자열, 숫자, 개행등을 작성하는 함수는 생략한다.