commit 22f66d0e6af558b9023c37c5683ac999efd6e90e
parent 7d2d6077216e8b55332366757c81d18bbf38f9f7
Author: Christos Margiolis <christos@margiolis.net>
Date: Wed, 23 Sep 2020 23:09:13 +0300
added erase, swap, shrink_to_fit and replace_str functions
Diffstat:
M | cstring.3 | | | 54 | +++++++++++++++++++++++++++++++++--------------------- |
M | cstring.c | | | 52 | ++++++++++++++++++++++++++++++++++++++++++++++++++-- |
M | cstring.h | | | 5 | ++++- |
D | test.c | | | 41 | ----------------------------------------- |
A | tests/test.c | | | 47 | +++++++++++++++++++++++++++++++++++++++++++++++ |
5 files changed, 134 insertions(+), 65 deletions(-)
diff --git a/cstring.3 b/cstring.3
@@ -4,68 +4,80 @@ cstring \- A simple and lightweight string library for C inspired by C++'s
STL string class
.SH FUNCTIONS
.TP
-.BR cstring\ cstring_create(const\ char\ *)
+.BR cstring\ cstring_create(const\ char\ *s)
Instanciates and initializes a
.I cstring
object.
.TP
-.BR void\ cstring_delete(cstring\ *)
+.BR void\ cstring_delete(cstring\ *cs)
Deallocate string.
.TP
-.BR void\ cstring_assign(cstring\ *,\ const\ char\ *)
+.BR void\ cstring_assign(cstring\ *cs,\ const\ char\ *s)
Assign a new string to the current string.
.TP
-.BR void\ cstring_append(cstring\ *,\ const\ char\ *)
-Append a string at the end of the current string.
+.BR void\ cstring_append(cstring\ *cs,\ const\ char\ *s)
+Append to end of string.
.TP
-.BR void\ cstring_insert(cstring\ *,\ const\ char\ *,\ size_t)
-Insert a string at a specific index.
+.BR void\ cstring_insert(cstring\ *cs,\ const\ char\ *s,\ size_t\ i)
+Insert at a specific index.
.TP
-.BR void\ cstring_push_back(cstring\ *,\ char)
+.BR void\ cstring_erase(cstring\ *cs,\ size_t\ pos,\ size_t\ len)
+Erase a portion of the string.
+.TP
+.BR void\ cstring_push_back(cstring\ *cs,\ char\ c)
Add a character at the end of the string.
.TP
-.BR void\ cstring_pop_back(cstring\ *)
+.BR void\ cstring_pop_back(cstring\ *cs)
Remove the last character in the string.
.TP
-.BR void\ cstring_replace_char(cstring\ *,\ const\ char\ *)
+.BR void\ cstring_replace_char(cstring\ *cs,\ size_t\ i,\ char\ c)
Replace character at a specific index.
.TP
-.BR cstring\ cstring_substr(cstring\ *,\ size_t\ ,\ size_t)
+.BR void\ cstring_replace_str(cstring\ *cs,\ const\ char\ *s,\ size_t\ pos,\ size_t\ len)
+Replace portion of the string.
+.TP
+.BR cstring\ cstring_substr(cstring\ *cs,\ size_t\ pos,\ size_t\ len)
Extract a substring from current string.
.TP
-.BR void\ cstring_clear(cstring\ *)
+.BR void\ cstring_swap(cstring\ *lhs,\ cstring\ *rhs)
+Swap contents of two strings.
+.TP
+.BR void\ cstring_shrink_to_fit(cstring\ *cs)
+Reduce string's capacity to its size.
+.TP
+.BR void\ cstring_clear(cstring\ *cs)
Erase the whole string.
.TP
-.BR size_t\ cstring_find(const\ cstring\ *,\ const\ char\ *)
+.BR size_t\ cstring_find(const\ cstring\ *cs,\ const\ char\ *s)
Find first occurence of a pattern in string.
.TP
-.BR size_t\ cstring_find_first_of(const\ cstring\ *,\ char)
+.BR size_t\ cstring_find_first_of(const\ cstring\ *cs,\ char\ c)
Find first occurence of a character in string.
.TP
-.BR size_t\ cstring_find_last_of(const\ cstring\ *,\ char)
+.BR size_t\ cstring_find_last_of(const\ cstring\ *cs,\ char\ c)
Find last occurence of a character in string.
.TP
-.BR char\ cstring_front(const\ cstring\ *)
+.BR char\ cstring_front(const\ cstring\ *cs)
Returns the first character of the string.
.TP
-.BR char\ cstring_back(const\ cstring\ *)
+.BR char\ cstring_back(const\ cstring\ *cs)
Returns the last character of the string.
.TP
-.BR int\ cstring_empty(const\ cstring\ *)
+.BR int\ cstring_empty(const\ cstring\ *cs)
Check to see if the string is empty.
.TP
-.BR char\ *cstring_copy(const\ char\ *)
+.BR char\ *cstring_copy(const\ char\ *s)
Make a copy of a given
.I const\ char\ *
.TP
-.BR void\ cstring_resize(cstring\ *,\ size_t)
+.BR void\ cstring_resize(cstring\ *cs,\ size_t\ newcapacity)
Resize the
.I str
array inside a given
.I cstring
struct.
.TP
-.BR cstring\ *cstring_getline(FILE\ *,\ cstring\ *,\ char)
+.BR cstring\ *cstring_getline(FILE\ *fd,\ cstring\ *cs,\ char\ delim)
Read a line from a
.I FILE
stream. Similar behavior to
diff --git a/cstring.c b/cstring.c
@@ -40,6 +40,7 @@ cstring_append(cstring *cs, const char *s)
strcat(cs->str, s);
cs->len = newlen;
}
+ else cstring_assign(cs, s); // TEST
}
void
@@ -65,6 +66,24 @@ cstring_insert(cstring *cs, const char *s, size_t i)
}
void
+cstring_erase(cstring *cs, size_t pos, size_t len)
+{
+ if (!CSTRING_OUT_OF_BOUNDS(cs, pos)
+ && !CSTRING_OUT_OF_BOUNDS(cs, len)
+ && pos < len)
+ {
+ size_t newlen = cs->len - len;
+ char *tmp = (char *)malloc(newlen + 1);
+ memcpy(tmp, cs->str, pos + 1);
+ memcpy(tmp + pos, cs->str + pos + len, newlen);
+ free(cs->str);
+ cs->len = newlen;
+ cs->str = tmp;
+ cs->str[cs->len] = '\0';
+ }
+}
+
+void
cstring_push_back(cstring *cs, char c)
{
if (CSTRING_EXCEEDS_CAPACITY(cs->len + 1, cs->capacity))
@@ -92,27 +111,56 @@ cstring_replace_char(cstring *cs, size_t i, char c)
cs->str[i] = c;
}
+void
+cstring_replace_str(cstring *cs, const char *s, size_t pos, size_t len)
+{
+ if (!CSTRING_OUT_OF_BOUNDS(cs, pos)
+ && !CSTRING_OUT_OF_BOUNDS(cs, len)
+ && !CSTRING_OUT_OF_BOUNDS(cs, pos + len)
+ && pos < len)
+ {
+ int i = pos;
+ for (; i < len && *s; s++, i++)
+ cs->str[i] = *s;
+ }
+}
+
cstring
cstring_substr(const cstring *cs, size_t pos, size_t len)
{
if (CSTRING_OUT_OF_BOUNDS(cs, pos)
|| CSTRING_OUT_OF_BOUNDS(cs, len)
- || len < pos)
+ || pos < len)
return cstring_create("");
cstring substr = cstring_create(&cs->str[pos]);
substr.len = len;
substr.str[len] = '\0';
- // maybe cstring_resize
+ cstring_shrink_to_fit(&substr);
return substr;
}
void
+cstring_swap(cstring *lhs, cstring *rhs)
+{
+ cstring tmp = *lhs;
+ *lhs = *rhs;
+ *rhs = tmp;
+}
+
+void
+cstring_shrink_to_fit(cstring *cs)
+{
+ cs->capacity = cs->len;
+}
+
+void
cstring_clear(cstring *cs)
{
if (!cstring_empty(cs)) free(cs->str);
cs->str = (char *)malloc(1);
cs->str[0] = '\0';
cs->len = 0;
+ cs->capacity = 0;
}
size_t
diff --git a/cstring.h b/cstring.h
@@ -26,10 +26,14 @@ extern void cstring_delete(cstring *);
extern void cstring_assign(cstring *, const char *);
extern void cstring_append(cstring *, const char *);
extern void cstring_insert(cstring *, const char *, size_t);
+extern void cstring_erase(cstring *, size_t, size_t);
extern void cstring_push_back(cstring *, char);
extern void cstring_pop_back(cstring *);
extern void cstring_replace_char(cstring *, size_t, char);
+extern void cstring_replace_str(cstring *, const char *, size_t, size_t);
extern cstring cstring_substr(const cstring *, size_t, size_t);
+extern void cstring_swap(cstring *, cstring *);
+extern void cstring_shrink_to_fit(cstring *);
extern void cstring_clear(cstring *);
extern size_t cstring_find(const cstring *, const char *);
extern size_t cstring_find_first_of(const cstring *, char);
@@ -40,7 +44,6 @@ extern int cstring_empty(const cstring *);
extern char *cstring_copy(const char *);
extern void cstring_resize(cstring *, size_t);
extern cstring *cstring_getline(FILE *, cstring *, char);
-//extern cstring *cstring_tok(const cstring *, const char *);
/* might be useless */
extern int cstring_equal(const cstring *, const cstring *);
diff --git a/test.c b/test.c
@@ -1,41 +0,0 @@
-#include "cstring.h"
-
-// Compilation: gcc test.c -lcstring
-
-int
-main(int argc, char **argv)
-{
- cstring s = cstring_create("Hello world");
- printf("cstring_create: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
-
- cstring_append(&s, "Append");
- printf("cstring_append: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
-
- cstring_assign(&s, "New string");
- printf("cstring_assign: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
-
- cstring_push_back(&s, 'c');
- printf("cstring_push_back: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
-
- cstring_insert(&s, "Inserted text", 4);
- printf("cstring_insert: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
-
- cstring_pop_back(&s);
- printf("cstring_pop_back: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
-
- cstring_clear(&s);
- printf("cstring_clear: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
-
- cstring_assign(&s, "CSTRING");
- printf("cstring_assign: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
- printf("cstring_front: %c\n", cstring_front(&s));
- printf("cstring_back: %c\n", cstring_back(&s));
-
- cstring_replace_char(&s, 3, 'x');
- printf("cstring_replace: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
-
- cstring_delete(&s);
- if (cstring_empty(&s)) printf("cstring_delete: Deleted string.\n");
-
- return 0;
-}
diff --git a/tests/test.c b/tests/test.c
@@ -0,0 +1,47 @@
+#include "cstring.h"
+
+// Compilation: gcc test.c -lcstring
+
+int
+main(int argc, char **argv)
+{
+ cstring s = cstring_create("Hello world");
+ printf("cstring_create: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
+
+ cstring_append(&s, "Append");
+ printf("cstring_append: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
+
+ cstring_assign(&s, "New string");
+ printf("cstring_assign: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
+
+ cstring_push_back(&s, 'c');
+ printf("cstring_push_back: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
+
+ cstring_insert(&s, "Inserted text", 4);
+ printf("cstring_insert: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
+
+ cstring_pop_back(&s);
+ printf("cstring_pop_back: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
+
+ cstring_clear(&s);
+ printf("cstring_clear: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
+
+ cstring_assign(&s, "CSTRING");
+ printf("cstring_assign: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
+ printf("cstring_front: %c\n", cstring_front(&s));
+ printf("cstring_back: %c\n", cstring_back(&s));
+
+ cstring_replace_char(&s, 3, 'x');
+ printf("cstring_replace_char: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
+
+ cstring_replace_str(&s, "hell", 0, strlen("hell"));
+ printf("cstring_replace_str: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
+
+ cstring_erase(&s, 1, 4);
+ printf("cstring_erase: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
+
+ cstring_delete(&s);
+ if (cstring_empty(&s)) printf("cstring_delete: Deleted string.\n");
+
+ return 0;
+}