diff --git a/functions.c b/functions.c index 2ed35b1..9daeafb 100644 --- a/functions.c +++ b/functions.c @@ -1,208 +1 @@ test -#include -#include -#include -#include "str.h" -#include "util.h" - -#define INIT_SZ 20 - -// Внутренняя функция, -// позволяет убедиться что строка может вместить как минимум newsz символов -void -_str_ensure(str *s, int newsz) -{ - int tmp; - newsz += 1; // добавляем единичку чтобы влез нулевой байт - if (newsz < s->capacity) - return; - - tmp = s->capacity * 2; - if (tmp > newsz) { - newsz = tmp; - } - s->ptr = xrealloc(s->ptr, newsz); - s->capacity = newsz; - } - - void - str_init(str *s) - { - assert(s); - s->len = 0; - s->capacity = INIT_SZ; - s->ptr = xmalloc(s->capacity); - s->ptr[0] = '\0'; - } - - void - str_deinit(str *s) - { - if (s->ptr) - free(s->ptr); - s->ptr = NULL; - s->len = 0; - s->capacity = 0; - } - - void - str_init_data(str *s, const char *initial) - { - assert(s && initial); - int len = strlen(initial); - s->len = len; - s->capacity = len + 1; - if (s->capacity < INIT_SZ) { - s->capacity = INIT_SZ; - } - s->ptr = xmalloc(s->capacity); - strcpy(s->ptr, initial); - } - - char * - str_data(str *s) - { - assert(s); - return s->ptr; - } - - void - str_set(str *s, char *cstr) - { - assert(s && cstr); - int len = strlen(cstr); - _str_ensure(s, len); - strcpy(s->ptr, cstr); - s->len = len; - } - - str - str_copy(str *s) - { - assert(s); - str new_str; - str_init(&new_str); - _str_ensure(&new_str, s->len); - strcpy(new_str.ptr, s->ptr); - new_str.len = s->len; - return new_str; - } - - int - str_count(str *s, char ch) - { - assert(s); - int count = 0; - for (int i = 0; i < s->len; i++) { - if (s->ptr[i] == ch) { - count++; - } - } - return count; - } - - void - str_append(str *s, char *cstr) - { - assert(s && cstr); - str_append_n(s, cstr, strlen(cstr)); - } - - void - str_append_n(str *s, char *cstr, int len) - { - assert(s && cstr); - _str_ensure(s, s->len + len); - memcpy(s->ptr + s->len, cstr, len); - s->len += len; - s->ptr[s->len] = '\0'; - } - - void - str_shrink(str *s, int len) - { - assert(s && len >= 0); - if (len > s->len) { - len = s->len; - } - s->len = len; - s->ptr[s->len] = '\0'; - } - - int - str_find(str *s, char *substr) - { - assert(s && substr); - char *p = strstr(s->ptr, substr); - if (p == NULL) - return -1; - return p - s->ptr; - } - - str - str_sub(str *s, int start_idx, int length) - { - assert(s && start_idx >= 0 && length >= 0); - - str s2; - str_init(&s2); - - if (start_idx >= s->len) { - return s2; // пустая строка - } - - if (start_idx + length > s->len) { - length = s->len - start_idx; - } - - _str_ensure(&s2, length); - memcpy(s2.ptr, s->ptr + start_idx, length); - s2.ptr[length] = '\0'; - s2.len = length; - - return s2; - } - - // Hint: you can create temporary string object! - int - str_replace(str *s, char *substr, char *replacement) - { - assert(s && substr && replacement); - - int count = 0; - str result; - str_init(&result); - - int substr_len = strlen(substr); - int replacement_len = strlen(replacement); - - char *current = s->ptr; - char *found; - - while ((found = strstr(current, substr)) != NULL) { - // Добавляем часть до найденной подстроки - int prefix_len = found - current; - if (prefix_len > 0) { - str_append_n(&result, current, prefix_len); - } - - // Добавляем замену - str_append_n(&result, replacement, replacement_len); - - current = found + substr_len; - count++; - } - - // Добавляем оставшуюся часть строки - if (*current != '\0') { - str_append(&result, current); - } - - // Заменяем исходную строку результатом - free(s->ptr); - s->ptr = result.ptr; - s->len = result.len; - s->capacity = result.capacity; - - return count; - } \ No newline at end of file