Однофайловая БД сортировка и фильтрация - 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;    //начало списка 
}

Объяснение кода листинга программы

  1. void SortIns(List *lst) - функция с типом возврата void, которая принимает указатель на структуру List в качестве аргумента.
  2. Node *tmp, *cur; - объявление двух указателей на Node, которые будут использоваться в функции.
  3. if((!lst->head)||(!lst->head->next)) return; - проверка на количество элементов в списке, если их менее двух, то функция возвращает управление.
  4. lst->tail = lst->head->next; - присвоение указателю tail значение head->next, то есть второй элемент в списке.
  5. while(lst->tail){ - начало цикла, который будет выполняться, пока есть элементы в списке.
  6. tmp = lst->tail; - присвоение указателю tmp значение tail, то есть текущий элемент в списке.
  7. cur = tmp->prev; - присвоение указателю cur значение prev текущего элемента в списке.
  8. lst->tail = lst->tail->next; - присвоение указателю tail значение next текущего элемента в списке.
  9. cur->next = tmp->next; - присвоение указателю next элемента, на который указывает указатель cur, значение next текущего элемента в списке.
  10. if(tmp->next) tmp->next->prev = cur; - если у текущего элемента есть следующий элемент, то устанавливаем указатель prev этого элемента на cur.
  11. while(cur&&(cmp(&cur->elem,&tmp->elem) > 0)) cur = cur->prev; - цикл, который будет выполняться, пока текущий элемент больше следующего элемента в списке или пока cur не станет NULL.
  12. if(cur){ - проверка, что cur не равен NULL.
  13. tmp->next = cur->next; - присвоение указателю next текущего элемента значение next элемента, на который указывает указатель cur.
  14. tmp->prev = cur; - присвоение указателю prev текущего элемента значение cur.
  15. cur->next = tmp; - присвоение указателю next элемента, на который указывает указатель cur, значение tmp.
  16. if(tmp->next) tmp->next->prev = tmp; - если у текущего элемента есть следующий элемент, то устанавливаем указатель prev этого элемента на tmp.
  17. else{ - если элемент вставляется в начало списка.
  18. tmp->next = lst->head; - присвоение указателю next текущего элемента значение head.
  19. tmp->prev = NULL; - присвоение указателю prev текущего элемента значение NULL.
  20. lst->head->prev = tmp; - присвоение указателю prev элемента, на который указывает указатель head, значение tmp.
  21. lst->head = tmp; - присвоение указателю head значение tmp.
  22. lst->tail = lst->head; - присвоение указателю tail значение head.
  23. return; - завершение функции.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

10   голосов , оценка 4 из 5
Похожие ответы