summaryrefslogtreecommitdiff
path: root/libft/ft_split.c
diff options
context:
space:
mode:
Diffstat (limited to 'libft/ft_split.c')
-rw-r--r--libft/ft_split.c91
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);
+}