stringview
This commit is contained in:
+48
-4
@@ -1,13 +1,57 @@
|
|||||||
#include "stringv.h"
|
#include "stringv.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
int main(void) {
|
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 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 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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
+117
-26
@@ -1,60 +1,151 @@
|
|||||||
#include "stringv.h"
|
#include "stringv.h"
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @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
|
* @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
|
* 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.
|
* characters.
|
||||||
*
|
*
|
||||||
* @param str pointer from the original string. It can be NULL.
|
* @param str pointer from the original string. It can be NULL.
|
||||||
*
|
*
|
||||||
* @return a StringView with the view of original string with corresponding
|
* @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) {
|
StringView sv_from_cstr(const char *str) {
|
||||||
if (str == NULL) {
|
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) {
|
if (sv == NULL) {
|
||||||
perror("sv_left: pointer is NULL\n");
|
return;
|
||||||
return STRING_VIEW_NULL;
|
|
||||||
}
|
}
|
||||||
if (sv->text == NULL) {
|
if (sv->text == NULL) {
|
||||||
perror("sv_left: text pointer is NULL\n");
|
return;
|
||||||
return STRING_VIEW_NULL;
|
|
||||||
}
|
}
|
||||||
if (sv->lenght < l) {
|
if (sv->length < l) {
|
||||||
perror("sv_left: text length is less than specified length\n");
|
return;
|
||||||
return STRING_VIEW_NULL;
|
|
||||||
}
|
}
|
||||||
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) {
|
if (sv == NULL) {
|
||||||
perror("sv_right: pointer is NULL\n");
|
return;
|
||||||
return STRING_VIEW_NULL;
|
|
||||||
}
|
}
|
||||||
if (sv->text == NULL) {
|
if (sv->text == NULL) {
|
||||||
perror("sv_right: text pointer is NULL\n");
|
return;
|
||||||
return STRING_VIEW_NULL;
|
|
||||||
}
|
}
|
||||||
if (sv->lenght < r) {
|
if (sv->length < r) {
|
||||||
perror("sv_right: text length is less than specified length\n");
|
return;
|
||||||
return STRING_VIEW_NULL;
|
|
||||||
}
|
}
|
||||||
size_t nlength = sv->lenght - r;
|
size_t nlength = sv->length - r;
|
||||||
return (StringView){.text = sv->text + nlength, .lenght = 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);
|
||||||
}
|
}
|
||||||
|
|||||||
+17
-3
@@ -1,14 +1,28 @@
|
|||||||
#ifndef STRING_VIEW_H
|
#ifndef STRING_VIEW_H
|
||||||
#define STRING_VIEW_H
|
#define STRING_VIEW_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
typedef struct StringView {
|
typedef struct StringView {
|
||||||
char *text;
|
char *text;
|
||||||
size_t lenght;
|
size_t length;
|
||||||
} StringView;
|
} StringView;
|
||||||
|
|
||||||
|
#define SV_NULL (StringView){.text = NULL, .length = 0}
|
||||||
|
|
||||||
StringView sv_from_cstr(const char *);
|
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
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user