Не работает копирование в списке - C (СИ)

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

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

Добрый день! Нужно реализовать копирование указанного элемента . Но почему то не работает . Подскажи в чем дело.
Листинг программы
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. typedef struct L {
  4. int value;
  5. char name[10];
  6. struct L *next, *prev;
  7. } ListItem;
  8. int main()
  9. {
  10. static ListItem base;
  11. static ListItem *current;
  12. static ListItem *pos;
  13. static int a,b,c,k,g;
  14. static int num;
  15. current = &base;
  16. base.next = base.prev = &base;
  17. num=0;
  18. /*Создание и добавления нового элемента до предыдущего*/
  19. do{
  20. pos = (ListItem*)malloc(sizeof(ListItem));
  21. printf("\nWhat is your name? \t");
  22. scanf("%s",&pos->name);
  23. printf("\nHow tall are you? \t");
  24. scanf("%d",&pos->value);
  25. if(pos->value==0){
  26. free(pos);
  27. break;
  28. }
  29. pos->next = current->next;
  30. pos->prev = current;
  31. current->next->prev = pos;
  32. current->next = pos;
  33. num++;
  34. }
  35. while(1);
  36. /*Печать всего списка*/
  37. pos=current->prev;
  38. while(pos!=&base)
  39. {
  40. printf("\nname=%s\ttall=%d\n",pos->name,pos->value);
  41. pos=pos->prev;
  42. }
  43. /*Копирование указанной ячейки и вставить до нее*/
  44. printf("\nVvedite do kakoi vstavit\t");
  45. scanf("%d",&k);
  46. pos=current->prev;
  47. for(c=1;c<k;c++){
  48. pos=pos->prev;
  49. }
  50. current->next=pos;
  51. pos = (ListItem*)malloc(sizeof(ListItem));
  52. pos->name=current->next->name;
  53. pos->value=current->next->value;
  54. pos->prev=current->next;
  55. pos->next=current->next->next;
  56. current->next->next->prev=pos;
  57. current->next->next=pos;
  58. num++;
  59. for(c=1;c<=num-k;c++){
  60. current->next=pos->prev;
  61. }
  62. pos=current->prev;
  63. while(pos!=&base)
  64. {
  65. printf("\nname=%s\ttall=%d\n",pos->name,pos->value);
  66. pos=pos->prev;
  67. }

Решение задачи: «Не работает копирование в списке»

textual
Листинг программы
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <malloc.h>
  4.  
  5. typedef struct node {
  6.     int  value;
  7.     char name[10];
  8.     struct node* next;
  9.     struct node* prev;
  10. } node_t;
  11.  
  12.  
  13. typedef struct {
  14.     node_t* head;
  15.     node_t* tail;
  16. } list_t;
  17.  
  18. void    list_init(list_t* l);
  19. int     list_add_front(list_t* l, const char* s, int n);
  20. int     list_add_back(list_t* l, const char* s, int n);
  21. node_t* list_insert(list_t* l, node_t* p, const char* s, int n);
  22. node_t* list_delete(list_t* l, node_t* p);
  23. void    list_clear(list_t* l);
  24.  
  25.  
  26. int main(void){
  27.     node_t* p;
  28.     list_t  l;
  29.  
  30.     list_init(&l);
  31.  
  32.     list_add_back(&l, "Uran",  1);
  33.     list_add_back(&l, "Mars",  2);
  34.     list_add_back(&l, "Venus", 3);
  35.  
  36.     list_add_front(&l, "Erath",  4);
  37.     list_add_front(&l, "Saturn", 5);
  38.     list_add_front(&l, "Neptun", 8);
  39.  
  40.     //вставить копию у чётных
  41.     for(p = l.head; p != NULL; p = p->next){
  42.         if(! (p->value % 2))
  43.             p = list_insert(&l, p, p->name, p->value);
  44.     }
  45.  
  46.  
  47.     //вывести с начало
  48.     for(p = l.head; p != NULL; p = p->next)
  49.         printf("%s\t%d\n", p->name, p->value);
  50.     putchar('\n');
  51.  
  52.     // вывести с конца
  53.     for(p = l.tail; p != NULL; p = p->prev)
  54.         printf("%s\t%d\n", p->name, p->value);
  55.     putchar('\n');
  56.  
  57.  
  58.     //удалить все чётные
  59.     p = l.head;
  60.     while(p != NULL){
  61.         if(!(p->value % 2)){
  62.             p = list_delete(&l, p);
  63.             continue;
  64.         }
  65.         p = p->next;
  66.     }
  67.  
  68.  
  69.     //вывести с начало
  70.     for(p = l.head; p != NULL; p = p->next)
  71.         printf("%s\t%d\n", p->name, p->value);
  72.     putchar('\n');
  73.  
  74.     // вывести с конца
  75.     for(p = l.tail; p != NULL; p = p->prev)
  76.         printf("%s\t%d\n", p->name, p->value);
  77.     putchar('\n');
  78.    
  79.     list_clear(&l);
  80.     return 0;
  81. }
  82.  
  83.  
  84. //инициализация
  85. void list_init(list_t* l){
  86.     l->head = l->tail = NULL;
  87. }
  88.  
  89.  
  90. //вставка в начало списка
  91. int list_add_front(list_t* l, const char* s, int n){
  92.     node_t* p = (node_t*)malloc(sizeof(node_t));
  93.     if(p != NULL){
  94.         p->next  = p->prev = NULL;
  95.         p->value = n;
  96.         strcpy(p->name, s);
  97.  
  98.         if(l->head == NULL)
  99.             l->head = l->tail = p;
  100.         else {
  101.             p->next       = l->head;
  102.             l->head->prev = p;
  103.             l->head       = p;
  104.         }
  105.     }
  106.     return (p != NULL);
  107. }
  108.  
  109.  
  110. //вставка в конец списка
  111. int list_add_back(list_t* l, const char* s, int n){
  112.     node_t* p = (node_t*)malloc(sizeof(node_t));
  113.     if(p != NULL){
  114.         p->next  = p->prev = NULL;
  115.         p->value = n;
  116.         strcpy(p->name, s);
  117.  
  118.         if(l->head == NULL)
  119.             l->head = l->tail = p;
  120.         else {
  121.             l->tail->next = p;
  122.             p->prev       = l->tail;
  123.             l->tail       = p;
  124.         }
  125.     }
  126.     return (p != NULL);
  127. }
  128.  
  129.  
  130. //вставка перед элементом
  131. node_t* list_insert(list_t* l, node_t* p, const char* s, int n){
  132.     node_t* t;
  133.     if(p == NULL)
  134.         return NULL;
  135.     else if(p == l->head){
  136.         if(list_add_front(l, s, n))
  137.             return l->head->next;
  138.         return NULL;
  139.     }
  140.    
  141.     t = (node_t*)malloc(sizeof(node_t));
  142.     if(t != NULL){
  143.         strcpy(t->name, s);
  144.         t->value  = n;
  145.         t->next   = p;
  146.         t->prev   = p->prev;
  147.         p->prev->next = t;
  148.         p->prev       = t;
  149.     }
  150.     return p;
  151. }
  152.  
  153.  
  154. //удаление элемента
  155. node_t* list_delete(list_t* l, node_t* p){
  156.     node_t* t;
  157.     if(p == NULL)
  158.         return NULL;
  159.     else if(p == l->head){
  160.  
  161.         l->head = l->head->next;
  162.         if(l->head != NULL)
  163.             l->head->prev = NULL;
  164.  
  165.         t = l->head;
  166.     } else if(p == l->tail){
  167.  
  168.         l->tail = l->tail->prev;
  169.         if(l->tail != NULL)
  170.             l->tail->next = NULL;
  171.  
  172.         t = l->tail;
  173.     } else {
  174.         p->prev->next = p->next;
  175.         p->next->prev = p->prev;
  176.         t = p->next;
  177.     }
  178.  
  179.     if(l->head == NULL)
  180.         l->tail = NULL;
  181.     free(p);
  182.     return t;
  183. }
  184.  
  185. //удаление всего списка
  186. void list_clear(list_t* l){
  187.     node_t* t;
  188.     while(l->head != NULL){
  189.         t       = l->head;
  190.         l->head = l->head->next;
  191.         free(t);
  192.     }
  193.     l->tail = NULL;
  194. }

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

В данном коде реализована работа со связанным списком. Список содержит узлы, каждый из которых включает в себя значение типа int и строку типа char, а также указатели на следующий и предыдущий узлы.

  1. Переменные и типы данных:
    • node_t - структура, представляющая один узел списка
    • list_t - структура, представляющая весь список
    • int - тип данных для значения в узле
    • char - тип данных для строки в узле
    • node_t* - указатель на узел
    • list_t* - указатель на список
    • const char* - указатель на строку
    • int* - указатель на значение
    • void* - указатель на любое значение
    • FILE* - указатель на файл (используется для отладки)
  2. Функции:
    • list_init - инициализирует список пустым
    • list_add_front - добавляет новый узел в начало списка
    • list_add_back - добавляет новый узел в конец списка
    • list_insert - вставляет новый узел перед указанным узлом
    • list_delete - удаляет узел из списка
    • list_clear - очищает список, освобождая память
  3. Основная часть программы:
    • Создается список и инициализируется пустым
    • В список добавляются узлы в произвольном порядке
    • Пытаются вставить копию каждого узла перед четными узлами
    • Выводят список с начала и с конца
    • Удаляют все четные узлы
    • Выводят список с начала и с конца
    • Очищают список
    • Возвращается 0, завершая программу Возможные проблемы и их решения:
    • При использовании функции strcpy для копирования строк, всегда выделяется 10 символов для строки name, даже если строка s короче. Это может привести к переполнению буфера, что является серьезной проблемой безопасности. Чтобы избежать этого, необходимо проверять длину строки s перед вызовом strcpy.
    • В коде нет обработки ошибок для операций с памятью (например, если malloc возвращает NULL). Хорошей практикой является обработка таких ошибок с помощью ifdef или try-catch конструкции.
    • Код не содержит комментариев, что затрудняет понимание его работы. Добавление комментариев к коду поможет другим разработчикам легче понять его структуру и функциональность.

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


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

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

6   голосов , оценка 4.167 из 5

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

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

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