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

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

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

Добрый день! Нужно реализовать копирование указанного элемента . Но почему то не работает . Подскажи в чем дело.
#include <stdio.h>
#include <stdlib.h>
 
typedef struct L {
int value;
char name[10];
struct L *next, *prev;
} ListItem;
 
int main()
{
static ListItem base;
static ListItem *current;
static ListItem *pos;
static int a,b,c,k,g;
static int num;
 
current = &base;
base.next = base.prev = &base;
num=0;
 
/*Создание и добавления нового элемента до предыдущего*/
do{
pos = (ListItem*)malloc(sizeof(ListItem));
printf("\nWhat is your name? \t");
scanf("%s",&pos->name);
printf("\nHow tall are you? \t");
scanf("%d",&pos->value);
 
if(pos->value==0){
    free(pos);
    break;
}
pos->next = current->next;
pos->prev = current;
current->next->prev = pos;
current->next = pos;
num++;
}
while(1);
/*Печать всего списка*/
pos=current->prev;
while(pos!=&base)
{
    printf("\nname=%s\ttall=%d\n",pos->name,pos->value);
    pos=pos->prev;
}
/*Копирование указанной ячейки и вставить до нее*/
printf("\nVvedite do kakoi vstavit\t");
 scanf("%d",&k);
 pos=current->prev;
 for(c=1;c<k;c++){
   pos=pos->prev;
 }
 current->next=pos;
 
pos = (ListItem*)malloc(sizeof(ListItem));
pos->name=current->next->name;
pos->value=current->next->value;
 
pos->prev=current->next;
pos->next=current->next->next;
current->next->next->prev=pos;
current->next->next=pos;
num++;
 
for(c=1;c<=num-k;c++){
    current->next=pos->prev;
}
 pos=current->prev;
 
while(pos!=&base)
{
    printf("\nname=%s\ttall=%d\n",pos->name,pos->value);
    pos=pos->prev;
    }

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

textual
Листинг программы
#include <stdio.h>
#include <string.h>
#include <malloc.h>
 
typedef struct node {
    int  value;
    char name[10];
    struct node* next;
    struct node* prev;
} node_t;
 
 
typedef struct {
    node_t* head;
    node_t* tail;
} list_t;
 
void    list_init(list_t* l);
int     list_add_front(list_t* l, const char* s, int n);
int     list_add_back(list_t* l, const char* s, int n);
node_t* list_insert(list_t* l, node_t* p, const char* s, int n);
node_t* list_delete(list_t* l, node_t* p);
void    list_clear(list_t* l);
 
 
int main(void){
    node_t* p;
    list_t  l;
 
    list_init(&l);
 
    list_add_back(&l, "Uran",  1); 
    list_add_back(&l, "Mars",  2); 
    list_add_back(&l, "Venus", 3); 
 
    list_add_front(&l, "Erath",  4);
    list_add_front(&l, "Saturn", 5);
    list_add_front(&l, "Neptun", 8);
 
    //вставить копию у чётных
    for(p = l.head; p != NULL; p = p->next){
        if(! (p->value % 2))
            p = list_insert(&l, p, p->name, p->value);
    }
 
 
    //вывести с начало
    for(p = l.head; p != NULL; p = p->next)
        printf("%s\t%d\n", p->name, p->value);
    putchar('\n');
 
    // вывести с конца
    for(p = l.tail; p != NULL; p = p->prev)
        printf("%s\t%d\n", p->name, p->value);
    putchar('\n');
 
 
    //удалить все чётные
    p = l.head;
    while(p != NULL){
        if(!(p->value % 2)){
            p = list_delete(&l, p);
            continue;
        }
        p = p->next;
    }
 
 
    //вывести с начало
    for(p = l.head; p != NULL; p = p->next)
        printf("%s\t%d\n", p->name, p->value);
    putchar('\n');
 
    // вывести с конца
    for(p = l.tail; p != NULL; p = p->prev)
        printf("%s\t%d\n", p->name, p->value);
    putchar('\n');
    
    list_clear(&l);
    return 0;
}
 
 
//инициализация
void list_init(list_t* l){
    l->head = l->tail = NULL;
}
 
 
//вставка в начало списка
int list_add_front(list_t* l, const char* s, int n){
    node_t* p = (node_t*)malloc(sizeof(node_t));
    if(p != NULL){
        p->next  = p->prev = NULL;
        p->value = n;
        strcpy(p->name, s);
 
        if(l->head == NULL)
            l->head = l->tail = p;
        else {
            p->next       = l->head;
            l->head->prev = p;
            l->head       = p;
        }
    }
    return (p != NULL);
}
 
 
//вставка в конец списка
int list_add_back(list_t* l, const char* s, int n){
    node_t* p = (node_t*)malloc(sizeof(node_t));
    if(p != NULL){
        p->next  = p->prev = NULL;
        p->value = n;
        strcpy(p->name, s);
 
        if(l->head == NULL)
            l->head = l->tail = p;
        else {
            l->tail->next = p;
            p->prev       = l->tail;
            l->tail       = p;
        }
    }
    return (p != NULL);
}
 
 
//вставка перед элементом
node_t* list_insert(list_t* l, node_t* p, const char* s, int n){
    node_t* t;
    if(p == NULL)
        return NULL;
    else if(p == l->head){
        if(list_add_front(l, s, n))
            return l->head->next;
        return NULL;
    }
    
    t = (node_t*)malloc(sizeof(node_t));
    if(t != NULL){
        strcpy(t->name, s);
        t->value  = n;
        t->next   = p;
        t->prev   = p->prev;
        p->prev->next = t;
        p->prev       = t;
    }
    return p;
}
 
 
//удаление элемента
node_t* list_delete(list_t* l, node_t* p){
    node_t* t;
    if(p == NULL)
        return NULL;
    else if(p == l->head){
 
        l->head = l->head->next;
        if(l->head != NULL)
            l->head->prev = NULL;
 
        t = l->head;
    } else if(p == l->tail){
 
        l->tail = l->tail->prev;
        if(l->tail != NULL)
            l->tail->next = NULL;
 
        t = l->tail;
    } else {
        p->prev->next = p->next;
        p->next->prev = p->prev;
        t = p->next;
    }
 
    if(l->head == NULL)
        l->tail = NULL;
    free(p);
    return t;
}
 
//удаление всего списка
void list_clear(list_t* l){
    node_t* t;
    while(l->head != NULL){
        t       = l->head;
        l->head = l->head->next;
        free(t);
    }
    l->tail = NULL;
}

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

В данном коде реализована работа со связанным списком. Список содержит узлы, каждый из которых включает в себя значение типа 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
Похожие ответы