diff options
Diffstat (limited to 'libft/ft_split.c')
-rw-r--r-- | libft/ft_split.c | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/libft/ft_split.c b/libft/ft_split.c new file mode 100644 index 0000000..bce2f72 --- /dev/null +++ b/libft/ft_split.c @@ -0,0 +1,91 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_split.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: kdx <kdx @student.42angouleme.fr +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2022/09/28 16:55:02 by kdx #+# #+# */ +/* Updated: 2022/10/13 22:34:28 by kdx ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" +#include <stdbool.h> + +static void *free_array(char **a) +{ + size_t i; + + if (a != NULL) + { + i = 0; + while (a[i] != NULL) + { + free(a[i]); + i += 1; + } + free(a); + } + return (NULL); +} + +static size_t skip_char(const char **s, char c, bool invert) +{ + size_t i; + const char *p; + + i = 0; + p = *s; + while (((!invert && *p == c) || (invert && *p != c)) && *p != '\0') + { + p += 1; + i += 1; + } + *s = p; + return (i); +} + +static size_t count_elems(const char *s, char c) +{ + size_t n_elem; + + n_elem = 0; + skip_char(&s, c, false); + while (*s != '\0') + { + skip_char(&s, c, true); + skip_char(&s, c, false); + n_elem += 1; + } + return (n_elem); +} + +char **ft_split(char const *s, char c) +{ + char **array; + size_t n_elem; + size_t arr_i; + const char *rem_s; + size_t len; + + if (s == NULL) + return (NULL); + n_elem = count_elems(s, c); + array = ft_calloc(n_elem + 1, sizeof(char *)); + if (array == NULL) + return (array); + skip_char(&s, c, false); + arr_i = 0; + while (arr_i < n_elem) + { + rem_s = s; + len = skip_char(&s, c, true); + array[arr_i] = ft_substr(rem_s, 0, len); + if (array[arr_i] == NULL) + return (free_array(array)); + arr_i += 1; + skip_char(&s, c, false); + } + return (array); +} |