Однофайловая БД сортировка и фильтрация - C (СИ)

Узнай цену своей работы

Формулировка задачи:

Добрый день уважаемы проблема вот в чём, не работает сортировка (компилю в Pellec C, может проблема в нём) и ещё не совсем понимаю как сделать фильтрацию, помогите кто чем может. Код прилагаю.
Листинг программы
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include<string.h>
  4. #include <locale.h>
  5. struct node
  6. {
  7. int elem;
  8. char* name;
  9. struct node* next, *prev;
  10. };
  11. typedef struct node Node;
  12. struct list
  13. {
  14. Node* head;
  15. Node* tail;
  16. };
  17. typedef struct list List;
  18. void initializeList(List* lst)
  19. {
  20. lst->head = 0;
  21. lst->tail = 0;
  22. }
  23. void push_back(List* lst, int numb , char nam [])
  24. {
  25. Node* t = (Node*) malloc(sizeof(Node));
  26. t->elem = numb;
  27. size_t length = strlen(nam);
  28. t->name = (char*) malloc(length + 1);
  29. strcpy(t->name, nam);;
  30. t->next = 0;
  31. if(lst->head == 0)
  32. {
  33. lst->head = t;
  34. lst->tail = t;
  35. return;
  36. }
  37. lst->tail->next = t;
  38. lst->tail = t;
  39. }
  40. void print_list(const List* const lst)
  41. {
  42. for(Node* tmp = lst->head; tmp; tmp = tmp->next)
  43. printf("%d %s\n", tmp->elem,tmp->name);
  44. }
  45. void free_list(List* lst)
  46. {
  47. lst->tail = lst->head;
  48. while(lst->head)
  49. {
  50. lst->head = lst->head->next;
  51. free(lst->tail);
  52. lst->tail = lst->head;
  53. }
  54. }
  55.  
  56. void SaveToFile(List* lst)
  57. {
  58. FILE *f;
  59. f = fopen("main.txt","wb"); // Открываем файл на запись данных
  60. if (f == NULL) { // Не удалось открыть - выводим сообщение об ошибке
  61. fprintf(stderr, "Не могу открыть файл на запись.\n");
  62. }
  63. int count = 0;
  64. for(Node* tmp = lst->head; tmp; tmp = tmp->next)
  65. { // Записываем в файл элементы по 1 за цикл, перемещаясь по списку пока не достигнем конца
  66. fprintf(f, "%d\r\n",tmp->elem);
  67. fprintf(f, "%s\r\n",tmp->name);
  68. count++;
  69. }
  70. // Закрываем файл
  71. fclose(f);
  72. // Выводим сообщение
  73. printf("\n --> Записано %d записей в файла main.txt\n",count);
  74. }
  75. void LoadInFile(List* lst)
  76. {
  77. FILE *f;
  78. f = fopen("main.txt","ab+"); // Открываем файл на запись данных
  79. if (f == NULL) { // Не удалось открыть - выводим сообщение об ошибке
  80. fprintf(stderr, "Не могу открыть файл на запись.\n");
  81. exit(0);
  82. }
  83. int count = 0;
  84. char* w = (char*)malloc(30 * sizeof(char));
  85. int q;
  86. while(fscanf (f, "%d%s", &(q),w) != EOF)
  87. {
  88. // printf("%d %s\n", q, w);
  89. push_back(lst,q,w);
  90. count++;
  91. }
  92. // Закрываем файл
  93. fclose(f);
  94. // Выводим сообщение
  95. printf("\n --> Загрузил %d записей в файла main.txt\n",count);
  96. }
  97. void search_elem(List* lst, int numb)
  98. { Node* tmp = lst->head;
  99. printf("Список искомых");
  100. printf("==============================\n");
  101. while(tmp!=NULL)
  102. {
  103. if(tmp->elem==numb)
  104. {
  105. printf(" %d",tmp->elem);
  106. printf(" %s\n",tmp->name);
  107. }
  108. tmp=tmp->next;
  109. }
  110. }
  111.  
  112. void Del_elem (List* lst,int n)
  113. {
  114. int i;
  115. Node *s = lst->head;
  116. Node *p;
  117. for (i = 1; i < n - 1; i ++)
  118. s = s->next;
  119. p = s->next;
  120. s->next = s->next->next;
  121. free(p);
  122. }
  123. void Red_elem (List* lst,int n)
  124. {
  125. int i;
  126. Node *s = lst->head;
  127. for (i = 1; i <= n - 1; i ++)
  128. s = s->next;
  129. printf("Редактируеммая запись");
  130. printf(" %d",s->elem);
  131. printf(" %s\n",s->name);
  132. printf("Введите новые значения");
  133. scanf("%d",&s->elem);
  134. scanf("%s",s->name);
  135. }
  136.  
  137. void ind_list(List* lst)
  138. {
  139. List ls;
  140. initializeList(&ls);
  141. int elem;
  142. char name[30];
  143. for(Node* tmp = lst->head; tmp; tmp = tmp->next)
  144. {
  145. printf(" %d",tmp->elem);
  146. printf(" %s\n",tmp->name);
  147. elem=tmp->elem;
  148. strcpy(name,tmp->name);
  149. printf(" %d",elem);
  150. printf(" %s\n",name);
  151. push_back(&ls,elem,name);
  152. }
  153. }
  154. void SortIns(List *lst)
  155. {
  156. Node *tmp, *cur; //Локальные переменные
  157. //Проверка: если в списке менее двух элементов, то
  158. //сортировать бессмысленно
  159. if((!lst->head)||(!lst->head->next)) return;
  160. //Устанавливаеся указатель на текущий элемент на второй
  161. lst->tail = lst->head->next; //элемент в списке
  162. //В цикле: пока не упорядочены все элементы
  163. while(lst->tail){
  164. //Указатель tmp - на текущий элемент в списке
  165. tmp = lst->tail;
  166. //Указатель cur - на предыдущий элемент в списке
  167. cur = lst->tail->prev;
  168. //Указатель на текущий элемент устанавливается на
  169. //следующий элемент в списке
  170. lst->tail = lst->tail->next;
  171. //Выделение элемента, на который установлен указатель
  172. cur->next = tmp->next; //tmp, из списка
  173. if(tmp->next) tmp->next->prev = cur;
  174. //В цикле производится поиск места вставки
  175. //while(cur&&(cmp(&cur->elem,&tmp->elem) > 0))
  176. cur = cur->prev;
  177. //Если выделенный элемент нужно вставить в «середину»
  178. if(cur){
  179. tmp->next = cur->next;
  180. tmp->prev = cur;
  181. cur->next = tmp;
  182. if(tmp->next) tmp->next->prev = tmp;
  183. }else{ //Иначе: в начало списка
  184. tmp->next = lst->head;
  185. tmp->prev = NULL;
  186. lst->head->prev = tmp;
  187. lst->head = tmp;
  188. }
  189. }
  190. //Установка указателя на текущий элемент на
  191. lst->tail = lst->head; //начало списка
  192. }
  193.  
  194. int main(void)
  195. {
  196. setlocale(LC_ALL, "RU");
  197. List lst;
  198. initializeList(&lst);
  199. LoadInFile(&lst);
  200. //SortIns(&lst);
  201. int input;
  202. do{
  203. printf("Выберите действие: ");
  204. printf("\n1 - Вывод списка на экран: ");
  205. printf("\n2 - Добавление записи: ");
  206. printf("\n3 - Редактирование записи: ");
  207. printf("\n4 - Удаление записи: ");
  208. printf("\n5 - Поиск записи:");
  209. printf("\n6 - Выход:\n");
  210. scanf( "%d", &input );
  211. system("cls");
  212. switch ( input ) {
  213. case 1:
  214. print_list(&lst);
  215. break;
  216. case 2:
  217. push_back(&lst, 10,"azz");
  218. break;
  219. case 3:
  220. Red_elem(&lst,2);
  221. break;
  222. case 4:
  223. Del_elem(&lst,4);
  224. ind_list(&lst);
  225. break;
  226. case 5:
  227. search_elem(&lst,10);
  228. break;
  229. case 6:
  230. SaveToFile(&lst);
  231. free_list(&lst);
  232. exit(0);
  233. break;
  234. default:
  235. printf( "Неправильный ввод.\n" );
  236. }
  237. }while(input!= 6);
  238. //int k;
  239. //char l[30];
  240. //scanf("%d",&k);
  241. //scanf("%s",l);
  242. /*printf("\n 1Список\n");
  243. print_list(&lst);
  244. // push_back(&lst, 10,"azz");
  245. //push_back(&lst, 15,"azz");
  246. // push_back(&lst, 25,"azz");
  247. // push_back(&lst, 1,"azz");
  248. //push_back(&lst, k,l);
  249. printf("\n 2Список\n");
  250. print_list(&lst);
  251. Red_elem(&lst,2);
  252. printf("\n 4Список\n");
  253. print_list(&lst);
  254. Del_elem(&lst,4);
  255. ind_list(&lst);
  256. printf("\n 3Список\n");
  257. print_list(&lst);
  258. search_elem(&lst,10);*/
  259. SaveToFile(&lst);
  260. free_list(&lst);
  261. }
Компилятор ругается на эту строчку
Листинг программы
  1. //while(cur&&(cmp(&cur->elem,&tmp->elem) > 0))
проблема во мне или в компиляторе?

Решение задачи: «Однофайловая БД сортировка и фильтрация»

textual
Листинг программы
  1. void SortIns(List *lst)
  2. {
  3.   Node *tmp, *cur;         //Локальные переменные
  4.   //Проверка: если в списке менее двух элементов, то
  5.   //сортировать бессмысленно
  6.   if((!lst->head)||(!lst->head->next)) return;
  7.   //Устанавливаеся указатель на текущий элемент на второй
  8.   lst->tail = lst->head->next;       //элемент в списке
  9.   //В цикле: пока не упорядочены все элементы
  10.   while(lst->tail){
  11.     //Указатель tmp - на текущий элемент в списке
  12.     tmp = lst->tail;
  13.     //Указатель cur - на предыдущий элемент в списке
  14.     cur = lst->tail->prev;
  15.     //Указатель на текущий элемент устанавливается на
  16.     //следующий элемент в списке
  17.     lst->tail = lst->tail->next;
  18.     //Выделение элемента, на который установлен указатель
  19.     cur->next = tmp->next;               //tmp, из списка
  20.     if(tmp->next) tmp->next->prev = cur;
  21.     //В цикле производится поиск места вставки
  22.    while(cur&&(cmp(&cur->elem,&tmp->elem) > 0))
  23.       cur = cur->prev;
  24.     //Если выделенный элемент нужно вставить в «середину»
  25.     if(cur){
  26.       tmp->next = cur->next;
  27.       tmp->prev = cur;
  28.       cur->next = tmp;
  29.       if(tmp->next) tmp->next->prev = tmp;
  30.     }else{  //Иначе: в начало списка
  31.       tmp->next = lst->head;
  32.       tmp->prev = NULL;
  33.       lst->head->prev = tmp;
  34.       lst->head = tmp;
  35.     }
  36.   }
  37.   //Установка указателя на текущий элемент на
  38.   lst->tail = lst->head;    //начало списка
  39. }

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

  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

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы