добавление структур в двусвязный список в c - PullRequest
1 голос
/ 15 января 2020

Я новичок в программировании (первый семестр), и примеры, которые я здесь нашел, всегда очень помогали мне при выполнении домашних заданий! Теперь я должен сделать немного больший проект, и я уже столько читал, но я просто не могу решить проблему.

Что мне нужно сделать

  1. Чтение данных из текста из файла
  2. Сортировать их в структуру с помощью strtok() (Поместить в struct, присваивая данные, прочитанные из файла, структурам полей)
  3. Добавить структуры в двусвязный список

Проблемы

  1. В списке есть только первая и последняя структура, когда я его печатаю, промежуточные структуры исчезают (первая запись "head" определяется в главной вместе с pNode=head;)
  2. Если я пытаюсь чтобы распечатать список в прямом порядке, он печатает последний элемент списка бесконечно.

Я попытался скопировать только те части, которые я считаю важными для проблемы. Поскольку я уже столько старался и даже не знаю, где искать ошибку, любая помощь или подсказка приветствуются. Большое спасибо заранее!

void read_file(struct node *pNode, FILE *fp) {
    struct node *head = pNode;
    head->next=NULL;
    head->prev=NULL;

    /*(fread, strtok_r, strtok,...)*/

    while (token1 != NULL) {
        //allocating memory for the structs
        struct node*new = calloc(1, sizeof(struct node));
        *new =*pNode;

        while (token2 != NULL) {
            new->index = (*token2 - 48);
            token2 = strtok(NULL, "\n"); //jump to next token (=next line)

            new->name = malloc(sizeof(char)*strlen(new->name)+1);
            strcpy(new->name, token2);
            token2 = strtok(NULL, "\n");

            /*(some more sorting into struct)*/

            /*ADD STRUCT TO LIST*/

            if (head->next==NULL){
                head->next=new;
                head->prev=NULL;
                new->prev=head;
                new->next=NULL;
            }

            new->next = head->next;
            head->next = new;
            new->next->prev = new;
            new->prev = head;
            head->prev = NULL;

            pNode=new;
        }

        token_recipe = strtok_r(NULL, "#", &temp); //jump to next token (=next recipe)
    }

    printf("\nLinked list in backwards order:\n");

    while (pNode != NULL) {
        printf("%s ", pNode->name);
        pNode= pNode->prev;
    }
    puts("\n");
}

1 Ответ

0 голосов
/ 15 января 2020

Здесь происходит беспорядочный клубок, который я постараюсь помочь и разгадать.

        if (head->next==NULL){
            head->next=new;
            head->prev=NULL;
            new->prev=head;
            new->next=NULL;
        }

        new->next = head->next;
        head->next = new;
        new->next->prev = new;
        new->prev = head;
        head->prev = NULL;

В первый раз у вас есть head и new. head->next равно NULL, поэтому вы делаете бит в блоке if и в итоге список выглядит следующим образом:

head <-> new

Затем вы указываете new->next на head->next ... что означает, что вы указываете new->next на new.

head <-> new -> new

new->next->prev = new, поэтому new->prev теперь также равно new

head -> new <-> new

, но затем вы исправляете его, чтобы указать его вернитесь к head и установите head->prev на NULL, что, вероятно, уже было, поскольку вы никогда не меняете его.

head <-> new -> new

И у вас все еще есть цикл l oop из new, указывающий на себя в качестве следующего узла.

Полностью очистите этот код. pNode - это предыдущий узел в вашем списке, и изначально он совпадает с head - это переменная, с которой вы должны ссылаться.

new->prev = pNode;
pNode->next = new;

предыдущее и следующее значения, которые не указаны, уже должны установить NULL (потому что вы используете calloc) или указывать на допустимое место в памяти, чтобы вам не приходилось с ними связываться.

И тогда вы правильно сделаете следующее в конец l oop

pNode = new;

, чтобы указать конец списка на последний созданный узел.

Вам также следует избавиться от следующей строки, поскольку new является fre sh новый узел - в pNode не должно быть ничего для копирования и при этом, поэтому вы устанавливаете следующие и предыдущие значения, которые вам не нужны, поскольку они уже правильно установлены на NULL.

*new =*pNode;
...