Однофайловая БД сортировка и фильтрация - 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;
- завершение функции.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д