fork download
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <malloc.h>
  4. #define MAX_DBLOCK 8
  5.  
  6. typedef struct {
  7. char** arr;
  8. size_t len;
  9. size_t cnt;
  10. } string_t;
  11.  
  12. static int ___string_alloc(string_t* s, size_t n);
  13. static int ___string_insert(string_t* s, size_t index, const char* str, size_t len);
  14. #define string_size(s) (s).cnt
  15. #define string_get(s, i) (s).arr[(i)]
  16.  
  17. void string_init(string_t* s);
  18. int string_add(string_t* s, const char* str);
  19. int string_addn(string_t* s, const char* str, size_t n);
  20. int string_insert(string_t* s, size_t index, const char* str);
  21. int string_set(string_t* s, size_t index, const char* str);
  22. int string_erase(string_t* s, size_t index, size_t cnt);
  23. void string_clear(string_t* s);
  24. int string_explode(string_t* s, const char* str, const char* delim);
  25.  
  26.  
  27. int main(void){
  28. size_t i;
  29. string_t s;
  30. char str[] = "заяц||белка||бобр||скунс||собака||"\
  31. "слон||тигр||лиса||соболь||шимпанзе||"\
  32. "росомаха||лев||пантера||пума||кугуар";
  33.  
  34. string_init(&s);
  35. string_explode(&s, str, "||");
  36.  
  37. for(i = 0; i < string_size(s); ++i)
  38. puts(string_get(s, i));
  39. putchar('\n');
  40.  
  41. string_insert(&s, 0, "\tпосле удаления");
  42. string_erase(&s, 3, 5);
  43. string_add(&s, "\tконец");
  44.  
  45. for(i = 0; i < string_size(s); ++i)
  46. puts(string_get(s, i));
  47.  
  48. string_clear(&s);
  49. return 0;
  50. }
  51.  
  52. //инициализация
  53. void string_init(string_t* s){
  54. s->arr = NULL;
  55. s->cnt = 0;
  56. s->len = MAX_DBLOCK;
  57. }
  58.  
  59. //вставка строки в конец массива
  60. int string_add(string_t* s, const char* str){
  61. return ___string_insert(s, s->cnt, str, strlen(str));
  62. }
  63.  
  64. //вставка строки в конец массива
  65. int string_addn(string_t* s, const char* str, size_t n){
  66. return ___string_insert(s, s->cnt, str, n);
  67. }
  68.  
  69. //произвольная вставка строки по-индексу
  70. int string_insert(string_t* s, size_t index, const char* str){
  71. return ___string_insert(s, index, str, strlen(str));
  72. }
  73.  
  74. //присвоить новую строку по-индексу
  75. int string_set(string_t* s, size_t index, const char* str){
  76. char* p;
  77. size_t n1, n2;
  78. if(index < s->cnt){
  79. n1 = strlen(s->arr[index]);
  80. n2 = strlen(str);
  81. if(n1 >= n2)
  82. strcpy(s->arr[index], str);
  83. else {
  84. p = (char*)realloc(s->arr[index], (n2 + 1) * sizeof(char));
  85. if(p == NULL)
  86. return 0;
  87. strcpy(p, str);
  88. s->arr[index] = p;
  89. }
  90. return 1;
  91. }
  92. return 0;
  93. }
  94.  
  95. //удаление элементов массива-строк
  96. int string_erase(string_t* s, size_t index, size_t cnt){
  97. size_t i, j;
  98. if((index + cnt) > s->cnt)
  99. return 0;
  100. for(i = index; i < (index + cnt); ++i)
  101. free(s->arr[i]);
  102.  
  103. s->cnt -= cnt;
  104. for(i = index, j = index + cnt; i < s->cnt; ++i)
  105. s->arr[i] = s->arr[j++];
  106. return 1;
  107. }
  108.  
  109. //удаление всего массива
  110. void string_clear(string_t* s){
  111. size_t i;
  112. for(i = 0; i < s->cnt; ++i)
  113. free(s->arr[i]);
  114.  
  115. if(s->arr != NULL)
  116. free(s->arr);
  117. string_init(s);
  118. }
  119.  
  120. //разделение строки по указанному разделителю
  121. int string_explode(string_t* s, const char* str, const char* delim){
  122. const char* p;
  123. size_t n2, n1 = strlen(delim);
  124.  
  125. s->cnt = 0;
  126. p = str;
  127. while((p = strstr(p, delim)) != NULL){
  128. if((n2 = (size_t)(p - str)) > 0){
  129. if(! string_addn(s, str, n2))
  130. return 0;
  131. }
  132. p += n1;
  133. str = p;
  134. }
  135. return (*str) ? string_add(s, str) : 1;
  136. }
  137.  
  138. //произвольная вставка строки по-индексу
  139. static int ___string_insert(string_t* s, size_t index, const char* str, size_t len){
  140. char* p;
  141. size_t i;
  142. if(index > s->cnt)
  143. return 0;
  144. if((p = (char*)malloc((len + 1) * sizeof(char))) == NULL)
  145. return 0;
  146. strncpy(p, str, len);
  147. p[len] = '\0';
  148.  
  149. if(! ___string_alloc(s, 1)){
  150. free(p);
  151. return 0;
  152. }
  153. for(i = s->cnt; i > index; --i)
  154. s->arr[i] = s->arr[i - 1];
  155.  
  156. s->arr[index] = p;
  157. ++(s->cnt);
  158. return 1;
  159. }
  160.  
  161. //аллокация для массива указателей
  162. static int ___string_alloc(string_t* s, size_t n){
  163. char** p;
  164. size_t i;
  165. if(s->arr == NULL){
  166. i = s->len;
  167. if(n > i)
  168. i = n;
  169. s->arr = (char**)malloc(i * sizeof(char*));
  170. if(s->arr == NULL)
  171. return 0;
  172. s->len = i;
  173. } else if((s->cnt + n) >= s->len){
  174. i = s->cnt + n + s->len / 2;
  175. p = (char**)realloc(s->arr, i * sizeof(char*));
  176. if(p == NULL)
  177. return 0;
  178. s->arr = p;
  179. s->len = i;
  180. }
  181. return 1;
  182. }
  183.  
Success #stdin #stdout 0s 2296KB
stdin
Standard input is empty
stdout
заяц
белка
бобр
скунс
собака
слон
тигр
лиса
соболь
шимпанзе
росомаха
лев
пантера
пума
кугуар

	после удаления
заяц
белка
лиса
соболь
шимпанзе
росомаха
лев
пантера
пума
кугуар
	конец