Сформировать массив строк. Удалить из него К последних строк - C (СИ)
Формулировка задачи:
Сформировать массив строк. Удалить из него К последних строк на языке СИ.
Реализовать функцию, организующую работу с динамически выделяемым многомерным массивом/ ● Массив (указатель на указатель или массив указателей) должен выделяться с помощью функций malloc () / calloc () в функции main (). ● Элементы массива могут вводиться в диалоговом режиме или задаваться с помощью датчика случайных чисел. ● Сформированный массив должен передаваться в качестве параметра в функцию. ● Для выполнения задания в функции допустимо динамически создавать новые массивы. ● Для работы со строками и областями памяти можно использовать функционал стандартной библиотеки языка Си. ● После достижения поставленных в задании целей необходимо удалять динамически выделенные массивы с помощью функции free (). ● В результате задания в функции main () должен быть выведен на экран результирующий массив, полученный в ходе выполнения реализованной функции.Решение задачи: «Сформировать массив строк. Удалить из него К последних строк»
textual
Листинг программы
#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)
puts(string_get(s, i));
putchar('\n');
string_insert(&s, 0, "\tпосле удаления");
string_erase(&s, 3, 5);
string_add(&s, "\tконец");
for(i = 0; i < string_size(s); ++i)
puts(string_get(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){
n1 = strlen(s->arr[index]);
n2 = strlen(str);
if(n1 >= n2)
strcpy(s->arr[index], str);
else {
p = (char*)realloc(s->arr[index], (n2 + 1) * sizeof(char));
if(p == NULL)
return 0;
strcpy(p, str);
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)
free(s->arr[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)
free(s->arr[i]);
if(s->arr != NULL)
free(s->arr);
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;
strncpy(p, str, len);
p[len] = '\0';
if(! ___string_alloc(s, 1)){
free(p);
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;
}
Объяснение кода листинга программы
- Объединение строк из массива, разделенных символом
||, в одну строку. - Вставка строки
после удаленияв начало массива. - Удаление из массива строк последних 5 элементов.
- Вставка строки
конецв конец массива. - Вывод на экран всех строк из массива.
- Вставка строки по индексу 0.
- Вставка строки по индексу 3.
- Вставка строки по индексу 5.
- Удаление элементов массива строк по индексам 3 и 5.
- Удаление всех элементов массива строк.
- Разделение строки
заяц||белка||бобр||скунс||собака||слон||тигр||лиса||соболь||шимпанзе||росомаха||лев||пантера||пума||кугуарна подстроки, используя символ||в качестве разделителя. - Вставка строки
после удаленияперед строкойскунс. - Удаление из массива строк последних 5 элементов.
- Вставка строки
конецпосле строкикугуар. - Вывод на экран всех подстрок из массива строк.
- Вставка строки
после удаленияв начало массива. - Удаление элементов массива строк по индексам 3 и 5.
- Удаление всех элементов массива строк.
- Разделение строки
заяц||белка||бобр||скунс||собака||слон||тигр||лиса||соболь||шимпанзе||росомаха||лев||пантера||пума||кугуарна подстроки, используя символ||в качестве разделителя. - Вставка строки
после удаленияперед строкойскунс.