From 87a500eadc6cb517f644fc36ffe98e1e83c28f79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agust=C3=ADn=20Ranieri?= Date: Sat, 21 Aug 2021 16:54:22 -0300 Subject: [PATCH] =?UTF-8?q?String:=20Usar=20delimitadores=20de=20m=C3=A1s?= =?UTF-8?q?=20de=20un=20caracter=20en=20split=20(#142)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * string: split with long delimitator * string: split with empty string as separator * string: split with null separator * string: string array usage in string split * string: split empty text and separator * string: split code style --- src/commons/string.c | 43 ++++++++++++++-------------- tests/unit-tests/test_string.c | 52 ++++++++++++++++++++++++++++++---- 2 files changed, 67 insertions(+), 28 deletions(-) diff --git a/src/commons/string.c b/src/commons/string.c index 20ae6be5..fcab1d60 100644 --- a/src/commons/string.c +++ b/src/commons/string.c @@ -26,7 +26,7 @@ static void _string_do(char *text, void (*closure)(char*)); static void _string_lower_element(char* ch); static void _string_upper_element(char* ch); void _string_append_with_format_list(const char* format, char** original, va_list arguments); -char** _string_split(char* text, char* separator, bool(*condition)(char*, int)); +char** _string_split(char* text, char* separator, bool(*is_last_token)(int)); static void _string_array_push(char*** array, char* text, int size); static char* _string_array_replace(char** array, int pos, char* text); @@ -145,15 +145,15 @@ bool string_equals_ignore_case(char *actual, char *expected) { } char **string_split(char *text, char *separator) { - bool _is_last_token(char* next, int _) { - return next != NULL; + bool _is_last_token(int _) { + return false; } return _string_split(text, separator, _is_last_token); } char** string_n_split(char *text, int n, char* separator) { - bool _is_last_token(char* next, int index) { - return next != NULL && index < (n - 1); + bool _is_last_token(int index) { + return index == (n - 1); } return _string_split(text, separator, _is_last_token); } @@ -286,27 +286,26 @@ void _string_append_with_format_list(const char* format, char** original, va_lis free(temporal); } -char** _string_split(char* text, char* separator, bool(*condition)(char*, int)) { +char** _string_split(char* text, char* separator, bool(*is_last_token)(int)) { char **substrings = string_array_new(); - int size = 0; - - char *text_to_iterate = string_duplicate(text); - char *next = text_to_iterate; - - while(condition(next, size)) { - char* token = strsep(&next, separator); - if(token == NULL) { - break; + int index = 0; + + char *end, *start = text; + if (separator != NULL) { + while ((end = strstr(start, separator)) != NULL && !is_last_token(index)) { + if (string_is_empty(separator)) { + if (string_length(start) > 1) + end = start + 1; + else + break; + } + _string_array_push(&substrings, string_substring_until(start, end - start), index++); + start = end + string_length(separator); } - _string_array_push(&substrings, string_duplicate(token), size); - size++; - }; - - if (next != NULL) { - _string_array_push(&substrings, string_duplicate(next), size); } - free(text_to_iterate); + _string_array_push(&substrings, string_duplicate(start), index); + return substrings; } diff --git a/tests/unit-tests/test_string.c b/tests/unit-tests/test_string.c index 07d7c3d8..fbaa02c5 100644 --- a/tests/unit-tests/test_string.c +++ b/tests/unit-tests/test_string.c @@ -182,9 +182,9 @@ context (test_string) { describe("Split") { - it("split_with_delimitators") { - char *line = "path/to/file"; - char** substrings = string_split(line, "/"); + it("split_with_separators") { + char *line = "path//to//file"; + char** substrings = string_split(line, "//"); should_ptr(substrings) not be null; should_string(substrings[0]) be equal to ("path"); @@ -195,7 +195,35 @@ context (test_string) { string_array_destroy(substrings); } end - it("split_starting_with_delimitator") { + it("split_with_empty_string_as_separator") { + char *line = "hello"; + char** substrings = string_split(line, ""); + + should_ptr(substrings) not be null; + should_string(substrings[0]) be equal to ("h"); + should_string(substrings[1]) be equal to ("e"); + should_string(substrings[2]) be equal to ("l"); + should_string(substrings[3]) be equal to ("l"); + should_string(substrings[4]) be equal to ("o"); + should_ptr(substrings[5]) be null; + + string_iterate_lines(substrings, (void*) free); + free(substrings); + } end + + it("split_with_null_separator") { + char *line = "path/to/file"; + char** substrings = string_split(line, NULL); + + should_ptr(substrings) not be null; + should_string(substrings[0]) be equal to ("path/to/file"); + should_ptr(substrings[1]) be null; + + string_iterate_lines(substrings, (void*) free); + free(substrings); + } end + + it("split_starting_with_separator") { char* line = "/path/to/file"; char** substrings = string_split(line, "/"); @@ -209,7 +237,7 @@ context (test_string) { string_array_destroy(substrings); } end - it("split_ending_with_delimitator") { + it("split_ending_with_separator") { char* line = "path/to/file/"; char** substrings = string_split(line, "/"); @@ -223,7 +251,7 @@ context (test_string) { string_array_destroy(substrings); } end - it("split_having_delimitators_in_between") { + it("split_having_separators_in_between") { char* line = "path/to//file"; char** substrings = string_split(line, "/"); @@ -249,6 +277,18 @@ context (test_string) { } end + it("split_is_empty_with_empty_separator") { + char* line = ""; + char** substrings = string_split(line, ""); + + should_ptr(substrings) not be null; + should_string(substrings[0]) be equal to(""); + should_ptr(substrings[1]) be null; + + string_array_destroy(substrings); + + } end + it("n_split_when_n_is_less_than_splitted_elements") { char *line = "Hola planeta tierra"; char** substrings = string_n_split(line, 2, " ");