diff --git a/c/stringview/main.c b/c/stringview/main.c index 57f3f78..da750a2 100644 --- a/c/stringview/main.c +++ b/c/stringview/main.c @@ -1,13 +1,57 @@ #include "stringv.h" #include int main(void) { - StringView s1 = sv_from_cstr("Hola mundo con string view"); + const char *data = " xHola mundo con string view- "; StringView s2 = sv_from_cstr("😊"); - StringView last = sv_right(&s1, 4); + + StringView hola = sv_from_cstr(data); + sv_ltrim(&hola); + sv_left(&hola, 4); + + StringView view = sv_from_cstr(data); + sv_rtrim(&view); + sv_right(&view, 4); + + StringView trim = sv_from_cstr(data); + sv_trim(&trim); printf("El string view contiene: %s\n", s2.text); - printf("El length es: %zu\n", s2.lenght); + printf("El length es: %zu\n", s2.length); - printf("last tiene:%.*s\n", (int)last.lenght, last.text); + printf("hola tiene:%.*s\n", (int)hola.length, hola.text); + printf("view tiene:%.*s\n", (int)view.length, view.text); + printf("trim tiene:[%.*s]\n", (int)trim.length, trim.text); + + StringView semana = sv_from_cstr( + "lunes, martes, miercoles, jueves, viernes, sabado, domingo"); + + StringView dia = sv_chop_by_delim(&semana, ','); + int d = 0; + while (dia.length > 0) { + d++; + sv_trim(&dia); + printf("dia%d: %.*s\n", d, (int)dia.length, dia.text); + dia = sv_chop_by_delim(&semana, ','); + } + + StringView c1 = sv_from_cstr("hdr2104"); + StringView c2 = sv_from_cstr("hdr2"); + + if (sv_equals(&c1, &c2)) { + printf("Las cadenas son iguales.\n"); + } else { + printf("Las cadenas NO son iguales.\n"); + } + + if (sv_starts_with(&c1, &c2) == true) { + printf("La cadena1 comienza con cadena2.\n"); + } else { + printf("La cadena1 NOOO comienza con cadena2.\n"); + } + + StringView test = sv_from_cstr("2"); + if (sv_ends_with(&c2, &test)) { + printf("La cedena dos termina como se quiere.\n"); + } return 0; } diff --git a/c/stringview/string b/c/stringview/string index 169823a..9695b67 100755 Binary files a/c/stringview/string and b/c/stringview/string differ diff --git a/c/stringview/stringv.c b/c/stringview/stringv.c index aeb5f48..fdc02af 100644 --- a/c/stringview/stringv.c +++ b/c/stringview/stringv.c @@ -1,60 +1,151 @@ #include "stringv.h" +#include +#include #include #include #include /* - * @brief Create a string view from a const char* and set their lenght + * @brief Create a string view from a const char* and set their length * * @details This string view provides a view of a string. It does not allocate * memory, therefore, it lives only while the source is alive. The - * lenght is a bytes number of the string. It does not represents the number of + * length is a bytes number of the string. It does not represents the number of * characters. * * @param str pointer from the original string. It can be NULL. * * @return a StringView with the view of original string with corresponding - * lenght. + * length. */ -#define STRING_VIEW_NULL (StringView){.text = NULL, .lenght = 0} - StringView sv_from_cstr(const char *str) { if (str == NULL) { - return STRING_VIEW_NULL; + return SV_NULL; } - return (StringView){.text = (char *)str, .lenght = strlen(str)}; + return (StringView){.text = (char *)str, .length = strlen(str)}; } -StringView sv_left(const StringView *sv, size_t l) { +void sv_left(StringView *sv, size_t l) { if (sv == NULL) { - perror("sv_left: pointer is NULL\n"); - return STRING_VIEW_NULL; + return; } if (sv->text == NULL) { - perror("sv_left: text pointer is NULL\n"); - return STRING_VIEW_NULL; + return; } - if (sv->lenght < l) { - perror("sv_left: text length is less than specified length\n"); - return STRING_VIEW_NULL; + if (sv->length < l) { + return; } - return (StringView){.text = sv->text, .lenght = l}; + sv->length = l; } -StringView sv_right(const StringView *sv, size_t r) { +void sv_right(StringView *sv, size_t r) { if (sv == NULL) { - perror("sv_right: pointer is NULL\n"); - return STRING_VIEW_NULL; + return; } if (sv->text == NULL) { - perror("sv_right: text pointer is NULL\n"); - return STRING_VIEW_NULL; + return; } - if (sv->lenght < r) { - perror("sv_right: text length is less than specified length\n"); - return STRING_VIEW_NULL; + if (sv->length < r) { + return; } - size_t nlength = sv->lenght - r; - return (StringView){.text = sv->text + nlength, .lenght = r}; + size_t nlength = sv->length - r; + sv->text = sv->text + nlength; + sv->length = r; +} + +void sv_ltrim(StringView *sv) { + if (sv == NULL) + return; + if (sv->length == 0) + return; + if (sv->text == NULL) + return; + + size_t offset = 0; + while (offset < sv->length && isspace((int)*(sv->text + offset))) { + offset++; + } + + if (offset > sv->length) + return; + sv->text += offset; + sv->length -= offset; +} + +void sv_rtrim(StringView *sv) { + if (sv == NULL) + return; + if (sv->length == 0) + return; + if (sv->text == NULL) + return; + + size_t offset = 0; + while (offset < sv->length && + isspace((int)*(sv->text + sv->length - 1 - offset))) { + offset++; + } + + if (offset > sv->length) + return; + sv->length -= offset; +} + +void sv_trim(StringView *sv) { + sv_ltrim(sv); + sv_rtrim(sv); +} + +int sv_index_of(StringView sv, char c) { + size_t offset = 0; + while (offset < sv.length && *(sv.text + offset) != c) { + offset++; + } + if (offset > sv.length) + return -1; + return offset; +} + +StringView sv_chop_by_delim(StringView *sv, char delim) { + StringView returnsv = SV_NULL; + int find = sv_index_of(*sv, delim); + if (!find) { + return returnsv; + } + returnsv.text = sv->text; + returnsv.length = find; + + sv->text += find + 1; + sv->length = sv->length - find; + + return returnsv; +} + +bool sv_equals(StringView *sv1, StringView *sv2) { + if (sv1 == NULL) + return false; + if (sv2 == NULL) + return false; + if (sv1->text == NULL) + return false; + if (sv2->text == NULL) + return false; + if (sv1->length != sv2->length) + return false; + return memcmp(sv1->text, sv2->text, sv1->length) == 0; +} + +bool sv_starts_with(StringView *sv, StringView *prefix) { + if (sv->length < prefix->length) + return false; + StringView cut = {.text = sv->text, .length = prefix->length}; + return sv_equals(&cut, prefix); +} +bool sv_ends_with(StringView *sv, StringView *suffix) { + if (sv->length < suffix->length) + return false; + StringView cut = {.text = sv->text, .length = sv->length}; + sv_right(&cut, suffix->length); + return sv_equals(&cut, suffix); } diff --git a/c/stringview/stringv.h b/c/stringview/stringv.h index e48caf2..cbc8f9a 100644 --- a/c/stringview/stringv.h +++ b/c/stringview/stringv.h @@ -1,14 +1,28 @@ #ifndef STRING_VIEW_H #define STRING_VIEW_H +#include #include typedef struct StringView { char *text; - size_t lenght; + size_t length; } StringView; +#define SV_NULL (StringView){.text = NULL, .length = 0} + StringView sv_from_cstr(const char *); -StringView sv_left(const StringView *sv, size_t l); -StringView sv_right(const StringView *sv, size_t l); + +void sv_left(StringView *sv, size_t l); +void sv_right(StringView *sv, size_t l); + +void sv_ltrim(StringView *sv); +void sv_rtrim(StringView *sv); +void sv_trim(StringView *sv); + +int sv_index_of(StringView sv, char c); +StringView sv_chop_by_delim(StringView *sv, char delim); +bool sv_equals(StringView *sv1, StringView *sv2); +bool sv_starts_with(StringView *sv, StringView *prefix); +bool sv_ends_with(StringView *sv, StringView *suffix); #endif