Dynamic String (ds)
Dynamic string library providing auto-expanding string operations including append, insert, delete, find, replace, split, and more.
Data Structure
struct ds_t {
char * data; /* String data terminated by '\0' */
size_t length; /* String length (excluding '\0') */
size_t capacity; /* Current capacity */
};
API
Allocation and Deallocation
struct ds_t * ds_alloc(void);
Allocate an empty string, initial capacity 16.
struct ds_t * ds_alloc_from_str(const char * str);
Create from a C string, copying the content.
struct ds_t * ds_alloc_from_buf(const void * buf, int len);
Create from the specified buffer, copying len bytes and automatically appending a '\0' terminator. Returns an empty string when buf is NULL or len <= 0.
void ds_free(struct ds_t * ds);
Free the string and the structure.
Accessors
size_t ds_length(struct ds_t * ds); /* String length */
size_t ds_capacity(struct ds_t * ds); /* Current capacity */
int ds_isempty(struct ds_t * ds); /* Returns 1 if empty */
const char * ds_cstr(struct ds_t * ds); /* C string pointer, NULL-safe, returns "" */
Copy and Substring
struct ds_t * ds_clone(struct ds_t * ds);
Deep copy, returns a new ds_t.
struct ds_t * ds_substr(struct ds_t * ds, size_t start, size_t len);
Extract a substring, returns a new ds_t. Returns an empty string when start exceeds length, len is automatically truncated when out of range.
Clear and Trim
void ds_clear(struct ds_t * ds);
Clear the string (length set to zero, memory not freed).
void ds_trim(struct ds_t * ds);
Remove leading and trailing whitespace characters.
Append and Prepend
int ds_append(struct ds_t * ds, const char * str);
int ds_append_char(struct ds_t * ds, const char c);
int ds_prepend(struct ds_t * ds, const char * str);
Returns 1 on success, 0 on failure.
Insert and Delete
int ds_insert(struct ds_t * ds, size_t pos, const char * str);
Insert a string at position pos, appended to the end when pos exceeds length.
int ds_delete(struct ds_t * ds, size_t start, size_t len);
Delete len characters starting from position start, automatically truncated when out of range.
Formatting
int ds_copy(struct ds_t * ds, const char * fmt, ...);
Replace the entire string content using printf-style formatting. Returns the number of characters written, 0 on failure.
int ds_concat(struct ds_t * ds, const char * fmt, ...);
Append to the end using printf-style formatting. Returns the number of characters appended, 0 on failure.
Find
int ds_find(struct ds_t * ds, const char * sub);
Find a substring from the left, returns the position index, -1 if not found. Returns length for empty substring.
int ds_rfind(struct ds_t * ds, const char * sub);
Find the last occurrence of a substring from the right, -1 if not found. Returns length for empty substring.
Replace
int ds_replace(struct ds_t * ds, const char * ostr, const char * nstr);
Replace all matching substrings, returns the number of replacements.
int ds_replace_first(struct ds_t * ds, const char * ostr, const char * nstr);
int ds_replace_last(struct ds_t * ds, const char * ostr, const char * nstr);
Replace the first/last match respectively. Returns 1 on success, 0 if not found.
Split Iteration
struct ds_iter_t * ds_iter_alloc(struct ds_t * ds, const char * delim);
void ds_iter_free(struct ds_iter_t * iter);
char * ds_iter_next(struct ds_iter_t * iter);
Split a string by delimiter, iterate to get each token. ds_iter_next returns NULL when finished.
Note: The iterator internally copies the original string data; modifying the original ds_t does not affect the iteration. The returned token pointer becomes invalid after
ds_iter_free.
Usage Examples
Basic Operations
struct ds_t * s = ds_alloc_from_str("hello");
ds_append(s, " world");
ds_prepend(s, ">> ");
/* ds_cstr(s) == ">> hello world" */
ds_free(s);
Formatting
struct ds_t * s = ds_alloc();
ds_copy(s, "count: %d", 42);
ds_concat(s, ", name: %s", "test");
/* ds_cstr(s) == "count: 42, name: test" */
ds_free(s);
Find and Replace
struct ds_t * s = ds_alloc_from_str("aabbccaabb");
ds_replace(s, "aa", "XX"); /* "XXbbccXXbb", returns 2 */
ds_replace_first(s, "bb", "YY"); /* "XXYYccXXbb", returns 1 */
ds_free(s);
Split Iteration
struct ds_t * s = ds_alloc_from_str("one,two,three");
struct ds_iter_t * iter = ds_iter_alloc(s, ",");
char * token;
while((token = ds_iter_next(iter)) != NULL)
{
/* in order: "one", "two", "three" */
}
ds_iter_free(iter);
ds_free(s);