#include <stdio.h>
#include <string.h>
#include <malloc.h>
#define MAX_DBLOCK 8
typedef struct {
char** arr;
size_t len;
size_t cnt;
} string_t;
static int ___string_alloc(string_t* s, size_t n);
static int ___string_insert(string_t* s, size_t index, const char* str, size_t len);
#define string_size(s) (s).cnt
#define string_get(s, i) (s).arr[(i)]
void string_init(string_t* s);
int string_add(string_t* s, const char* str);
int string_addn(string_t* s, const char* str, size_t n);
int string_insert(string_t* s, size_t index, const char* str);
int string_set(string_t* s, size_t index, const char* str);
int string_erase(string_t* s, size_t index, size_t cnt);
void string_clear(string_t* s);
int string_explode(string_t* s, const char* str, const char* delim);
int main(void){
size_t i;
string_t s;
char str[] = "заяц||белка||бобр||скунс||собака||"\
"слон||тигр||лиса||соболь||шимпанзе||"\
"росомаха||лев||пантера||пума||кугуар";
string_init(&s);
string_explode(&s, str, "||");
for(i = 0; i < string_size(s); ++i)
string_insert(&s, 0, "\tпосле удаления");
string_erase(&s, 3, 5);
string_add(&s, "\tконец");
for(i = 0; i < string_size(s); ++i)
string_clear(&s);
return 0;
}
//инициализация
void string_init(string_t* s){
s->arr = NULL;
s->cnt = 0;
s->len = MAX_DBLOCK;
}
//вставка строки в конец массива
int string_add(string_t* s, const char* str){
return ___string_insert
(s
, s
->cnt
, str
, strlen(str
)); }
//вставка строки в конец массива
int string_addn(string_t* s, const char* str, size_t n){
return ___string_insert(s, s->cnt, str, n);
}
//произвольная вставка строки по-индексу
int string_insert(string_t* s, size_t index, const char* str){
return ___string_insert
(s
, index
, str
, strlen(str
)); }
//присвоить новую строку по-индексу
int string_set(string_t* s, size_t index, const char* str){
char* p;
size_t n1, n2;
if(index < s->cnt){
if(n1 >= n2)
else {
p
= (char*)realloc(s
->arr
[index
], (n2
+ 1) * sizeof(char)); if(p == NULL)
return 0;
s->arr[index] = p;
}
return 1;
}
return 0;
}
//удаление элементов массива-строк
int string_erase(string_t* s, size_t index, size_t cnt){
size_t i, j;
if((index + cnt) > s->cnt)
return 0;
for(i = index; i < (index + cnt); ++i)
s->cnt -= cnt;
for(i = index, j = index + cnt; i < s->cnt; ++i)
s->arr[i] = s->arr[j++];
return 1;
}
//удаление всего массива
void string_clear(string_t* s){
size_t i;
for(i = 0; i < s->cnt; ++i)
if(s->arr != NULL)
string_init(s);
}
//разделение строки по указанному разделителю
int string_explode(string_t* s, const char* str, const char* delim){
const char* p;
size_t n2
, n1
= strlen(delim
);
s->cnt = 0;
p = str;
while((p
= strstr(p
, delim
)) != NULL
){ if((n2 = (size_t)(p - str)) > 0){
if(! string_addn(s, str, n2))
return 0;
}
p += n1;
str = p;
}
return (*str) ? string_add(s, str) : 1;
}
//произвольная вставка строки по-индексу
static int ___string_insert(string_t* s, size_t index, const char* str, size_t len){
char* p;
size_t i;
if(index > s->cnt)
return 0;
if((p
= (char*)malloc((len
+ 1) * sizeof(char))) == NULL
) return 0;
p[len] = '\0';
if(! ___string_alloc(s, 1)){
return 0;
}
for(i = s->cnt; i > index; --i)
s->arr[i] = s->arr[i - 1];
s->arr[index] = p;
++(s->cnt);
return 1;
}
//аллокация для массива указателей
static int ___string_alloc(string_t* s, size_t n){
char** p;
size_t i;
if(s->arr == NULL){
i = s->len;
if(n > i)
i = n;
s
->arr
= (char**)malloc(i
* sizeof(char*)); if(s->arr == NULL)
return 0;
s->len = i;
} else if((s->cnt + n) >= s->len){
i = s->cnt + n + s->len / 2;
p
= (char**)realloc(s
->arr
, i
* sizeof(char*)); if(p == NULL)
return 0;
s->arr = p;
s->len = i;
}
return 1;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPG1hbGxvYy5oPgojZGVmaW5lIE1BWF9EQkxPQ0sgICAgOAoKdHlwZWRlZiBzdHJ1Y3QgewoJY2hhcioqIGFycjsKCXNpemVfdCBsZW47CglzaXplX3QgY250Owp9IHN0cmluZ190OwoKc3RhdGljIGludCBfX19zdHJpbmdfYWxsb2Moc3RyaW5nX3QqIHMsIHNpemVfdCBuKTsKc3RhdGljIGludCBfX19zdHJpbmdfaW5zZXJ0KHN0cmluZ190KiBzLCBzaXplX3QgaW5kZXgsIGNvbnN0IGNoYXIqIHN0ciwgc2l6ZV90IGxlbik7CiNkZWZpbmUgc3RyaW5nX3NpemUocykgICAocykuY250CiNkZWZpbmUgc3RyaW5nX2dldChzLCBpKSAocykuYXJyWyhpKV0KCnZvaWQgc3RyaW5nX2luaXQoc3RyaW5nX3QqIHMpOwppbnQgIHN0cmluZ19hZGQoc3RyaW5nX3QqIHMsIGNvbnN0IGNoYXIqIHN0cik7CmludCAgc3RyaW5nX2FkZG4oc3RyaW5nX3QqIHMsIGNvbnN0IGNoYXIqIHN0ciwgc2l6ZV90IG4pOwppbnQgIHN0cmluZ19pbnNlcnQoc3RyaW5nX3QqIHMsIHNpemVfdCBpbmRleCwgY29uc3QgY2hhciogc3RyKTsKaW50ICBzdHJpbmdfc2V0KHN0cmluZ190KiBzLCBzaXplX3QgaW5kZXgsIGNvbnN0IGNoYXIqIHN0cik7CmludCAgc3RyaW5nX2VyYXNlKHN0cmluZ190KiBzLCBzaXplX3QgaW5kZXgsIHNpemVfdCBjbnQpOwp2b2lkIHN0cmluZ19jbGVhcihzdHJpbmdfdCogcyk7CmludCAgc3RyaW5nX2V4cGxvZGUoc3RyaW5nX3QqIHMsIGNvbnN0IGNoYXIqIHN0ciwgY29uc3QgY2hhciogZGVsaW0pOwoKCmludCBtYWluKHZvaWQpewoJc2l6ZV90IGk7CglzdHJpbmdfdCBzOwoJY2hhciBzdHJbXSA9ICLQt9Cw0Y/Rhnx80LHQtdC70LrQsHx80LHQvtCx0YB8fNGB0LrRg9C90YF8fNGB0L7QsdCw0LrQsHx8IlwKCSAgICAgICAgICAgICAi0YHQu9C+0L18fNGC0LjQs9GAfHzQu9C40YHQsHx80YHQvtCx0L7Qu9GMfHzRiNC40LzQv9Cw0L3Qt9C1fHwiXAoJICAgICAgICAgICAgICLRgNC+0YHQvtC80LDRhdCwfHzQu9C10LJ8fNC/0LDQvdGC0LXRgNCwfHzQv9GD0LzQsHx80LrRg9Cz0YPQsNGAIjsKCglzdHJpbmdfaW5pdCgmcyk7CglzdHJpbmdfZXhwbG9kZSgmcywgc3RyLCAifHwiKTsKCglmb3IoaSA9IDA7IGkgPCBzdHJpbmdfc2l6ZShzKTsgKytpKQoJCXB1dHMoc3RyaW5nX2dldChzLCBpKSk7CglwdXRjaGFyKCdcbicpOwoKCXN0cmluZ19pbnNlcnQoJnMsIDAsICJcdNC/0L7RgdC70LUg0YPQtNCw0LvQtdC90LjRjyIpOwoJc3RyaW5nX2VyYXNlKCZzLCAzLCA1KTsKCXN0cmluZ19hZGQoJnMsICJcdNC60L7QvdC10YYiKTsKCglmb3IoaSA9IDA7IGkgPCBzdHJpbmdfc2l6ZShzKTsgKytpKQoJCXB1dHMoc3RyaW5nX2dldChzLCBpKSk7CgoJc3RyaW5nX2NsZWFyKCZzKTsKCXJldHVybiAwOwp9CgovL9C40L3QuNGG0LjQsNC70LjQt9Cw0YbQuNGPCnZvaWQgc3RyaW5nX2luaXQoc3RyaW5nX3QqIHMpewoJcy0+YXJyID0gTlVMTDsKCXMtPmNudCA9IDA7CglzLT5sZW4gPSBNQVhfREJMT0NLOwp9CgovL9Cy0YHRgtCw0LLQutCwINGB0YLRgNC+0LrQuCDQsiDQutC+0L3QtdGGINC80LDRgdGB0LjQstCwCmludCBzdHJpbmdfYWRkKHN0cmluZ190KiBzLCBjb25zdCBjaGFyKiBzdHIpewoJcmV0dXJuIF9fX3N0cmluZ19pbnNlcnQocywgcy0+Y250LCBzdHIsIHN0cmxlbihzdHIpKTsKfQoKLy/QstGB0YLQsNCy0LrQsCDRgdGC0YDQvtC60Lgg0LIg0LrQvtC90LXRhiDQvNCw0YHRgdC40LLQsAppbnQgc3RyaW5nX2FkZG4oc3RyaW5nX3QqIHMsIGNvbnN0IGNoYXIqIHN0ciwgc2l6ZV90IG4pewoJcmV0dXJuIF9fX3N0cmluZ19pbnNlcnQocywgcy0+Y250LCBzdHIsIG4pOwp9CgovL9C/0YDQvtC40LfQstC+0LvRjNC90LDRjyDQstGB0YLQsNCy0LrQsCDRgdGC0YDQvtC60Lgg0L/Qvi3QuNC90LTQtdC60YHRgwppbnQgc3RyaW5nX2luc2VydChzdHJpbmdfdCogcywgc2l6ZV90IGluZGV4LCBjb25zdCBjaGFyKiBzdHIpewoJcmV0dXJuIF9fX3N0cmluZ19pbnNlcnQocywgaW5kZXgsIHN0ciwgc3RybGVuKHN0cikpOwp9CgovL9C/0YDQuNGB0LLQvtC40YLRjCDQvdC+0LLRg9GOINGB0YLRgNC+0LrRgyDQv9C+LdC40L3QtNC10LrRgdGDCmludCBzdHJpbmdfc2V0KHN0cmluZ190KiBzLCBzaXplX3QgaW5kZXgsIGNvbnN0IGNoYXIqIHN0cil7CgljaGFyKiAgcDsKCXNpemVfdCBuMSwgbjI7CglpZihpbmRleCA8IHMtPmNudCl7CgkJbjEgPSBzdHJsZW4ocy0+YXJyW2luZGV4XSk7CgkJbjIgPSBzdHJsZW4oc3RyKTsKCQlpZihuMSA+PSBuMikKCQkJc3RyY3B5KHMtPmFycltpbmRleF0sIHN0cik7CgkJZWxzZSB7CgkJCXAgPSAoY2hhciopcmVhbGxvYyhzLT5hcnJbaW5kZXhdLCAobjIgKyAxKSAqIHNpemVvZihjaGFyKSk7CgkJCWlmKHAgPT0gTlVMTCkKCQkJCXJldHVybiAwOwoJCQlzdHJjcHkocCwgc3RyKTsKCQkJcy0+YXJyW2luZGV4XSA9IHA7CgkJfQoJCXJldHVybiAxOwoJfQoJcmV0dXJuIDA7Cn0KCi8v0YPQtNCw0LvQtdC90LjQtSDRjdC70LXQvNC10L3RgtC+0LIg0LzQsNGB0YHQuNCy0LAt0YHRgtGA0L7QugppbnQgc3RyaW5nX2VyYXNlKHN0cmluZ190KiBzLCBzaXplX3QgaW5kZXgsIHNpemVfdCBjbnQpewoJc2l6ZV90IGksIGo7CglpZigoaW5kZXggKyBjbnQpID4gcy0+Y250KQoJCXJldHVybiAwOwoJZm9yKGkgPSBpbmRleDsgaSA8IChpbmRleCArIGNudCk7ICsraSkKCQlmcmVlKHMtPmFycltpXSk7CgoJcy0+Y250IC09IGNudDsKCWZvcihpID0gaW5kZXgsIGogPSBpbmRleCArIGNudDsgaSA8IHMtPmNudDsgKytpKQoJCXMtPmFycltpXSA9IHMtPmFycltqKytdOwoJcmV0dXJuIDE7Cn0KCi8v0YPQtNCw0LvQtdC90LjQtSDQstGB0LXQs9C+INC80LDRgdGB0LjQstCwCnZvaWQgc3RyaW5nX2NsZWFyKHN0cmluZ190KiBzKXsJCglzaXplX3QgaTsKCWZvcihpID0gMDsgaSA8IHMtPmNudDsgKytpKQoJCWZyZWUocy0+YXJyW2ldKTsKCglpZihzLT5hcnIgIT0gTlVMTCkKCQlmcmVlKHMtPmFycik7CglzdHJpbmdfaW5pdChzKTsKfQoKLy/RgNCw0LfQtNC10LvQtdC90LjQtSDRgdGC0YDQvtC60Lgg0L/QviDRg9C60LDQt9Cw0L3QvdC+0LzRgyDRgNCw0LfQtNC10LvQuNGC0LXQu9GOCmludCBzdHJpbmdfZXhwbG9kZShzdHJpbmdfdCogcywgY29uc3QgY2hhciogc3RyLCBjb25zdCBjaGFyKiBkZWxpbSl7Cgljb25zdCBjaGFyKiBwOwoJc2l6ZV90IG4yLCBuMSA9IHN0cmxlbihkZWxpbSk7CgoJcy0+Y250ID0gMDsKCXAgICAgICA9IHN0cjsKCXdoaWxlKChwID0gc3Ryc3RyKHAsIGRlbGltKSkgIT0gTlVMTCl7CgkJaWYoKG4yID0gKHNpemVfdCkocCAtIHN0cikpID4gMCl7CgkJCWlmKCEgc3RyaW5nX2FkZG4ocywgc3RyLCBuMikpCgkJCQlyZXR1cm4gMDsKCQl9CgkJcCAgKz0gbjE7CgkJc3RyID0gcDsKCX0KCXJldHVybiAoKnN0cikgPyBzdHJpbmdfYWRkKHMsIHN0cikgOiAxOwp9CgovL9C/0YDQvtC40LfQstC+0LvRjNC90LDRjyDQstGB0YLQsNCy0LrQsCDRgdGC0YDQvtC60Lgg0L/Qvi3QuNC90LTQtdC60YHRgwpzdGF0aWMgaW50IF9fX3N0cmluZ19pbnNlcnQoc3RyaW5nX3QqIHMsIHNpemVfdCBpbmRleCwgY29uc3QgY2hhciogc3RyLCBzaXplX3QgbGVuKXsKCWNoYXIqICBwOwoJc2l6ZV90IGk7CglpZihpbmRleCA+IHMtPmNudCkKCQlyZXR1cm4gMDsKCWlmKChwID0gKGNoYXIqKW1hbGxvYygobGVuICsgMSkgKiBzaXplb2YoY2hhcikpKSA9PSBOVUxMKQoJCXJldHVybiAwOwoJc3RybmNweShwLCBzdHIsIGxlbik7CglwW2xlbl0gPSAnXDAnOwoKCWlmKCEgX19fc3RyaW5nX2FsbG9jKHMsIDEpKXsKCQlmcmVlKHApOwoJCXJldHVybiAwOwoJfQoJZm9yKGkgPSBzLT5jbnQ7IGkgPiBpbmRleDsgLS1pKQoJCXMtPmFycltpXSA9IHMtPmFycltpIC0gMV07CgoJcy0+YXJyW2luZGV4XSA9IHA7CgkrKyhzLT5jbnQpOwoJcmV0dXJuIDE7Cn0KCi8v0LDQu9C70L7QutCw0YbQuNGPINC00LvRjyDQvNCw0YHRgdC40LLQsCDRg9C60LDQt9Cw0YLQtdC70LXQuQpzdGF0aWMgaW50IF9fX3N0cmluZ19hbGxvYyhzdHJpbmdfdCogcywgc2l6ZV90IG4pewoJY2hhcioqIHA7CglzaXplX3QgaTsKCWlmKHMtPmFyciA9PSBOVUxMKXsKCQlpID0gcy0+bGVuOwoJCWlmKG4gPiBpKQoJCQlpID0gbjsKCQlzLT5hcnIgPSAoY2hhcioqKW1hbGxvYyhpICogc2l6ZW9mKGNoYXIqKSk7CgkJaWYocy0+YXJyID09IE5VTEwpCgkJCXJldHVybiAwOwoJCXMtPmxlbiA9IGk7Cgl9IGVsc2UgaWYoKHMtPmNudCArIG4pID49IHMtPmxlbil7CgkJaSA9IHMtPmNudCArIG4gKyBzLT5sZW4gLyAyOwoJCXAgPSAoY2hhcioqKXJlYWxsb2Mocy0+YXJyLCBpICogc2l6ZW9mKGNoYXIqKSk7CgkJaWYocCA9PSBOVUxMKQoJCQlyZXR1cm4gMDsKCQlzLT5hcnIgPSBwOwoJCXMtPmxlbiA9IGk7Cgl9CglyZXR1cm4gMTsKfQo=