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