Однофайловая БД сортировка и фильтрация - C (СИ)
Формулировка задачи:
Добрый день уважаемы проблема вот в чём, не работает сортировка (компилю в Pellec C, может проблема в нём) и ещё не совсем понимаю как сделать фильтрацию, помогите кто чем может. Код прилагаю.
Компилятор ругается на эту строчку проблема во мне или в компиляторе?
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#include <locale.h>
struct node
{
int elem;
char* name;
struct node* next, *prev;
};
typedef struct node Node;
struct list
{
Node* head;
Node* tail;
};
typedef struct list List;
void initializeList(List* lst)
{
lst->head = 0;
lst->tail = 0;
}
void push_back(List* lst, int numb , char nam [])
{
Node* t = (Node*) malloc(sizeof(Node));
t->elem = numb;
size_t length = strlen(nam);
t->name = (char*) malloc(length + 1);
strcpy(t->name, nam);;
t->next = 0;
if(lst->head == 0)
{
lst->head = t;
lst->tail = t;
return;
}
lst->tail->next = t;
lst->tail = t;
}
void print_list(const List* const lst)
{
for(Node* tmp = lst->head; tmp; tmp = tmp->next)
printf("%d %s\n", tmp->elem,tmp->name);
}
void free_list(List* lst)
{
lst->tail = lst->head;
while(lst->head)
{
lst->head = lst->head->next;
free(lst->tail);
lst->tail = lst->head;
}
}
void SaveToFile(List* lst)
{
FILE *f;
f = fopen("main.txt","wb"); // Открываем файл на запись данных
if (f == NULL) { // Не удалось открыть - выводим сообщение об ошибке
fprintf(stderr, "Не могу открыть файл на запись.\n");
}
int count = 0;
for(Node* tmp = lst->head; tmp; tmp = tmp->next)
{ // Записываем в файл элементы по 1 за цикл, перемещаясь по списку пока не достигнем конца
fprintf(f, "%d\r\n",tmp->elem);
fprintf(f, "%s\r\n",tmp->name);
count++;
}
// Закрываем файл
fclose(f);
// Выводим сообщение
printf("\n --> Записано %d записей в файла main.txt\n",count);
}
void LoadInFile(List* lst)
{
FILE *f;
f = fopen("main.txt","ab+"); // Открываем файл на запись данных
if (f == NULL) { // Не удалось открыть - выводим сообщение об ошибке
fprintf(stderr, "Не могу открыть файл на запись.\n");
exit(0);
}
int count = 0;
char* w = (char*)malloc(30 * sizeof(char));
int q;
while(fscanf (f, "%d%s", &(q),w) != EOF)
{
// printf("%d %s\n", q, w);
push_back(lst,q,w);
count++;
}
// Закрываем файл
fclose(f);
// Выводим сообщение
printf("\n --> Загрузил %d записей в файла main.txt\n",count);
}
void search_elem(List* lst, int numb)
{ Node* tmp = lst->head;
printf("Список искомых");
printf("==============================\n");
while(tmp!=NULL)
{
if(tmp->elem==numb)
{
printf(" %d",tmp->elem);
printf(" %s\n",tmp->name);
}
tmp=tmp->next;
}
}
void Del_elem (List* lst,int n)
{
int i;
Node *s = lst->head;
Node *p;
for (i = 1; i < n - 1; i ++)
s = s->next;
p = s->next;
s->next = s->next->next;
free(p);
}
void Red_elem (List* lst,int n)
{
int i;
Node *s = lst->head;
for (i = 1; i <= n - 1; i ++)
s = s->next;
printf("Редактируеммая запись");
printf(" %d",s->elem);
printf(" %s\n",s->name);
printf("Введите новые значения");
scanf("%d",&s->elem);
scanf("%s",s->name);
}
void ind_list(List* lst)
{
List ls;
initializeList(&ls);
int elem;
char name[30];
for(Node* tmp = lst->head; tmp; tmp = tmp->next)
{
printf(" %d",tmp->elem);
printf(" %s\n",tmp->name);
elem=tmp->elem;
strcpy(name,tmp->name);
printf(" %d",elem);
printf(" %s\n",name);
push_back(&ls,elem,name);
}
}
void SortIns(List *lst)
{
Node *tmp, *cur; //Локальные переменные
//Проверка: если в списке менее двух элементов, то
//сортировать бессмысленно
if((!lst->head)||(!lst->head->next)) return;
//Устанавливаеся указатель на текущий элемент на второй
lst->tail = lst->head->next; //элемент в списке
//В цикле: пока не упорядочены все элементы
while(lst->tail){
//Указатель tmp - на текущий элемент в списке
tmp = lst->tail;
//Указатель cur - на предыдущий элемент в списке
cur = lst->tail->prev;
//Указатель на текущий элемент устанавливается на
//следующий элемент в списке
lst->tail = lst->tail->next;
//Выделение элемента, на который установлен указатель
cur->next = tmp->next; //tmp, из списка
if(tmp->next) tmp->next->prev = cur;
//В цикле производится поиск места вставки
//while(cur&&(cmp(&cur->elem,&tmp->elem) > 0))
cur = cur->prev;
//Если выделенный элемент нужно вставить в «середину»
if(cur){
tmp->next = cur->next;
tmp->prev = cur;
cur->next = tmp;
if(tmp->next) tmp->next->prev = tmp;
}else{ //Иначе: в начало списка
tmp->next = lst->head;
tmp->prev = NULL;
lst->head->prev = tmp;
lst->head = tmp;
}
}
//Установка указателя на текущий элемент на
lst->tail = lst->head; //начало списка
}
int main(void)
{
setlocale(LC_ALL, "RU");
List lst;
initializeList(&lst);
LoadInFile(&lst);
//SortIns(&lst);
int input;
do{
printf("Выберите действие: ");
printf("\n1 - Вывод списка на экран: ");
printf("\n2 - Добавление записи: ");
printf("\n3 - Редактирование записи: ");
printf("\n4 - Удаление записи: ");
printf("\n5 - Поиск записи:");
printf("\n6 - Выход:\n");
scanf( "%d", &input );
system("cls");
switch ( input ) {
case 1:
print_list(&lst);
break;
case 2:
push_back(&lst, 10,"azz");
break;
case 3:
Red_elem(&lst,2);
break;
case 4:
Del_elem(&lst,4);
ind_list(&lst);
break;
case 5:
search_elem(&lst,10);
break;
case 6:
SaveToFile(&lst);
free_list(&lst);
exit(0);
break;
default:
printf( "Неправильный ввод.\n" );
}
}while(input!= 6);
//int k;
//char l[30];
//scanf("%d",&k);
//scanf("%s",l);
/*printf("\n 1Список\n");
print_list(&lst);
// push_back(&lst, 10,"azz");
//push_back(&lst, 15,"azz");
// push_back(&lst, 25,"azz");
// push_back(&lst, 1,"azz");
//push_back(&lst, k,l);
printf("\n 2Список\n");
print_list(&lst);
Red_elem(&lst,2);
printf("\n 4Список\n");
print_list(&lst);
Del_elem(&lst,4);
ind_list(&lst);
printf("\n 3Список\n");
print_list(&lst);
search_elem(&lst,10);*/
SaveToFile(&lst);
free_list(&lst);
}//while(cur&&(cmp(&cur->elem,&tmp->elem) > 0))
Решение задачи: «Однофайловая БД сортировка и фильтрация»
textual
Листинг программы
void SortIns(List *lst)
{
Node *tmp, *cur; //Локальные переменные
//Проверка: если в списке менее двух элементов, то
//сортировать бессмысленно
if((!lst->head)||(!lst->head->next)) return;
//Устанавливаеся указатель на текущий элемент на второй
lst->tail = lst->head->next; //элемент в списке
//В цикле: пока не упорядочены все элементы
while(lst->tail){
//Указатель tmp - на текущий элемент в списке
tmp = lst->tail;
//Указатель cur - на предыдущий элемент в списке
cur = lst->tail->prev;
//Указатель на текущий элемент устанавливается на
//следующий элемент в списке
lst->tail = lst->tail->next;
//Выделение элемента, на который установлен указатель
cur->next = tmp->next; //tmp, из списка
if(tmp->next) tmp->next->prev = cur;
//В цикле производится поиск места вставки
while(cur&&(cmp(&cur->elem,&tmp->elem) > 0))
cur = cur->prev;
//Если выделенный элемент нужно вставить в «середину»
if(cur){
tmp->next = cur->next;
tmp->prev = cur;
cur->next = tmp;
if(tmp->next) tmp->next->prev = tmp;
}else{ //Иначе: в начало списка
tmp->next = lst->head;
tmp->prev = NULL;
lst->head->prev = tmp;
lst->head = tmp;
}
}
//Установка указателя на текущий элемент на
lst->tail = lst->head; //начало списка
}
Объяснение кода листинга программы
void SortIns(List *lst)- функция с типом возвратаvoid, которая принимает указатель на структуруListв качестве аргумента.Node *tmp, *cur;- объявление двух указателей наNode, которые будут использоваться в функции.if((!lst->head)||(!lst->head->next)) return;- проверка на количество элементов в списке, если их менее двух, то функция возвращает управление.lst->tail = lst->head->next;- присвоение указателюtailзначениеhead->next, то есть второй элемент в списке.while(lst->tail){- начало цикла, который будет выполняться, пока есть элементы в списке.tmp = lst->tail;- присвоение указателюtmpзначениеtail, то есть текущий элемент в списке.cur = tmp->prev;- присвоение указателюcurзначениеprevтекущего элемента в списке.lst->tail = lst->tail->next;- присвоение указателюtailзначениеnextтекущего элемента в списке.cur->next = tmp->next;- присвоение указателюnextэлемента, на который указывает указательcur, значениеnextтекущего элемента в списке.if(tmp->next) tmp->next->prev = cur;- если у текущего элемента есть следующий элемент, то устанавливаем указательprevэтого элемента наcur.while(cur&&(cmp(&cur->elem,&tmp->elem) > 0)) cur = cur->prev;- цикл, который будет выполняться, пока текущий элемент больше следующего элемента в списке или покаcurне станетNULL.if(cur){- проверка, чтоcurне равенNULL.tmp->next = cur->next;- присвоение указателюnextтекущего элемента значениеnextэлемента, на который указывает указательcur.tmp->prev = cur;- присвоение указателюprevтекущего элемента значениеcur.cur->next = tmp;- присвоение указателюnextэлемента, на который указывает указательcur, значениеtmp.if(tmp->next) tmp->next->prev = tmp;- если у текущего элемента есть следующий элемент, то устанавливаем указательprevэтого элемента наtmp.else{- если элемент вставляется в начало списка.tmp->next = lst->head;- присвоение указателюnextтекущего элемента значениеhead.tmp->prev = NULL;- присвоение указателюprevтекущего элемента значениеNULL.lst->head->prev = tmp;- присвоение указателюprevэлемента, на который указывает указательhead, значениеtmp.lst->head = tmp;- присвоение указателюheadзначениеtmp.lst->tail = lst->head;- присвоение указателюtailзначениеhead.return;- завершение функции.