1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
|
# Introduction
This describes the API of string type **cstr_t**.
## Types
| Type name | Type definition | Used to represent... |
|:------------------|:---------------------------------|:---------------------------|
| `cstr_t` | `struct { const char *str; }` | The string type |
| `cstr_value_t` | `char` | The string element type |
| `cstr_iter_t` | `struct { cstr_value_t *val; }` | cstr_t iterator |
## Constants and macros
| Name | Value |
|:---------------------------|:-----------------|
| `cstr_npos` | `-1ull` |
## Header file
All cstr definitions and prototypes may be included in your C source file by including a single header file.
```c
#include "stc/cstr.h"
```
## Methods
### Construction
The interfaces to create a cstr_t object:
```c
cstr_t cstr_init(void); (1)
cstr_t cstr_with_capacity(size_t cap); (2)
cstr_t cstr_with_size(size_t len, char fill); (3)
cstr_t cstr_from(const char* str); (4)
cstr_t cstr_from_n(const char* str, size_t len); (5)
cstr_t cstr_from_fmt(const char* fmt, ...); (6)
cstr_t cstr_clone(cstr_t s); (7)
```
(1) Create an empty cstr_t, (2) with capacity `cap`. (3) Create a cstr_t by repeating the `fill` character `len` times. (4) Construct a cstr_t from a const char* str, and (5) limit the length by `len` and `strlen(str)`. (6) Construct a string from a formatted const char* `fmt` and arguments, using `printf()` formatting. (7) Construct a new string by cloning another cstr_t `s`.
### Destruction
```c
void cstr_del(cstr_t *self);
```
Free the allocated memory used by string.
### Get string properties
```c
size_t cstr_size(cstr_t s);
size_t cstr_length(cstr_t s);
size_t cstr_capacity(cstr_t s);
bool cstr_empty(cstr_t s);
```
### Get references to front and back of a cstr_t
```c
char* cstr_front(cstr_t* self);
char* cstr_back(cstr_t* self);
```
### Reserve capcacity, resize, and clear
```c
size_t cstr_reserve(cstr_t* self, size_t cap);
void cstr_resize(cstr_t* self, size_t len, char fill);
void cstr_clear(cstr_t* self);
```
### Assignment and transfer of ownership
```c
cstr_t* cstr_assign(cstr_t* self, const char* str); (1)
cstr_t* cstr_assign_n(cstr_t* self, const char* str, size_t len); (2)
cstr_t* cstr_take(cstr_t* self, cstr_t s); (3)
cstr_t cstr_move(cstr_t* self); (4)
```
(1) Assign `str` to `*self`, (2) assign substring `str` limited by `len` and `strlen(str)`. (3) Take the constructed or moved string `s`, i.e., no allocation takes place. (4) Explicitly move `*self` to the caller of the method; `*self` becomes an empty string after move.
### Append and insert characters
```c
cstr_t* cstr_append(cstr_t* self, const char* str); (1)
cstr_t* cstr_append_n(cstr_t* self, const char* str, size_t len); (2)
cstr_t* cstr_push_back(cstr_t* self, char ch); (3)
void cstr_insert(cstr_t* self, size_t pos, const char* str); (4)
void cstr_insert_n(cstr_t* self, size_t pos, const char* str, size_t n); (5)
```
(1) Append `str` to `*self`. (2) Append substring `str` limited by `len`. (3), Append character `ch`.
(4) Insert a string at the specified position (5), or insert string limited with n / strlen(str).
### Erase characters
```c
void cstr_erase(cstr_t* self, size_t pos, size_t n);
void cstr_pop_back(cstr_t* self);
```
### Replace substring
```c
void cstr_replace(cstr_t* self, size_t pos, size_t len, const char* str);
void cstr_replace_n(cstr_t* self, size_t pos, size_t len, const char* str, size_t n);
```
### Search for substring, case sensitive / insensitive
```c
size_t cstr_find(cstr_t s, const char* substr);
size_t cstr_find_n(cstr_t s, const char* substr, size_t pos, size_t nlen);
bool cstr_contains(cstr_t s, const char* substr);
bool cstr_begins_with(cstr_t s, const char* substr);
bool cstr_ends_with(cstr_t s, const char* substr);
size_t cstr_ifind_n(cstr_t s, const char* substr, size_t pos, size_t nlen);
bool cstr_icontains(cstr_t s, const char* substr);
bool cstr_ibegins_with(cstr_t s, const char* substr);
bool cstr_iends_with(cstr_t s, const char* substr);
```
### Comparisons and equality
```c
bool cstr_equals(cstr_t s, const char* str);
bool cstr_equals_s(cstr_t s, cstr_t s2);
int cstr_compare(const cstr_t *s1, const cstr_t *s2);
bool cstr_iequals(cstr_t s, const char* str);
```
### Iterator methods
```c
cstr_iter_t cstr_begin(cstr_t* self); (1)
cstr_iter_t cstr_end(cstr_t* self); (2)
void cstr_next(cstr_iter_t* it); (3)
char* cstr_itval(cstr_iter_t it); (4)
```
To iterate though a string, one can use the generic `c_foreach` macro. E.g. `c_foreach (i, cstr, mystr) printf("%c", *i.val);`. This is equivalent to `for (size_t i=0; i<cstr_size(mystr); ++i) printf("%c", mystr.str[i])`.
```c
bool cstr_getline(cstr_t *self, FILE *stream);
bool cstr_getdelim(cstr_t *self, int delim, FILE *stream);
```
## Other string methods
### Non-members
```c
int c_strncasecmp(const char* s1, const char* s2, size_t n);
char* c_strnfind(const char* str, const char* needle, size_t nmax);
char* c_istrnfind(const char* str, const char* needle, size_t nmax);
uint32_t c_string_hash(const char* str);
```
### Helper methods
```c
const char* cstr_to_raw(const cstr_t* x);
int cstr_compare_raw(const char** x, const char** y);
bool cstr_equals_raw(const char** x, const char** y);
uint32_t cstr_hash_raw(const char* const* spp, size_t ignored);
```
|