Одной из моих функций является случайное удаление элементов из списка - PullRequest
0 голосов
/ 03 июня 2019

Я пытаюсь создать «библиотеку», в которой есть отсортированные по алфавиту каталоги, в каждом из которых есть книги также в алфавитном порядке. Как часть функции deletebook (не включена, потому что ее еще нет), я написал функцию, которая находит каталог книги. Функция работает, но она удаляет книги в процессе (я думаю), что не хорошо. Как изменить его, чтобы он не удалял их?

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

struct book
{
    char *title;
    int number;
    char *country;
    struct book* new;
};

struct catalog
{
    char *name;
    struct catalog* next;
    struct book* firstbook;
};

void printList(struct catalog *head)
{
    struct catalog *temp = head;

    while(temp != NULL)
    {
        struct book* book = temp->firstbook;
        if(book == NULL)
        {
            printf("%s\n", temp->name);
        }
        while(book != NULL)
        {
            printf("%s  ", temp->name);
            printf("%s  ", book->title);
            printf("%d  ", book->number);
            printf("%s\n", book->country);
            book = book->new;
        }
        temp = temp->next;
    }
}
struct catalog *newcatalog(char *new_name)
{
    struct catalog* new_node = (struct catalog*) malloc(sizeof(struct catalog));
    new_node->name = malloc(strlen(new_name)+1);
    strcpy(new_node->name, new_name);
    new_node->next =  NULL;
    new_node->firstbook = NULL;
    return new_node;
}

struct book *newbook(char *booktitle, int number, char *country)
{
    struct book* newbook = (struct book*) malloc(sizeof(struct book));
    newbook->title = malloc(strlen(booktitle)+1);
    newbook->country = malloc(strlen(country)+1);
    strcpy(newbook->title, booktitle);
    strcpy(newbook->country, country);
    newbook->number = number;
    newbook->new = NULL;
    return newbook;
}
struct catalog *findcatalog(struct catalog** head, char *catalogname)
{
    struct catalog* current;
    current = *head;
    while(current != NULL)
    {
        if(!strcmp(current->name,catalogname))
        {
            return current;
        }
        current = current->next;
    }
    return NULL;
}


struct catalog *findbookcatalog(struct catalog** head, int number) //function that deletes a book when used
{
    struct catalog* current;
    current = *head;
    while(current != NULL)
    {
        while(current->firstbook != NULL)
        {
            if(current->firstbook->number == number)
            {
                return current;
            }
            current->firstbook = current->firstbook->new;
        }
        current = current->next;
    }
    return NULL;
}
struct book *findbook(struct catalog** head, int number)
{
    struct catalog* current = findbookcatalog(head, number);
    struct book* booklocation;
    while(current->firstbook != NULL)
    {
        booklocation = current->firstbook;
        if(current->firstbook->number == number)
        {
            return booklocation;
        }
    current->firstbook = current->firstbook->new;
    }
    return NULL;
}

void sortedBookInsert(struct catalog** head, char *catalogname, char *booktitle, int number, char *country)
{
    struct catalog* searched;
    struct book* pom;
    struct book* ksiazka = newbook(booktitle, number, country);
    searched = findcatalog(head, catalogname);

    if(searched->firstbook == NULL || strcmp(searched->firstbook->title, ksiazka->title)>0)
    {
        ksiazka->new =searched->firstbook;
        searched->firstbook = ksiazka;
    }
    else
    { pom = searched->firstbook;
        while(pom->new!= NULL && strcmp(searched->firstbook->title, ksiazka->title)< 0)
        {
            pom = pom->new;
        }
        ksiazka->new = pom->new;
        pom->new = ksiazka;
    }
}
void sortedInsert(struct catalog** head,char *name)
{
    struct catalog* current;
    struct catalog* new_node = newcatalog(name);
    if(new_node == NULL)
    {
        return;
    }

    if (*head == NULL || strcmp((*head)->name, new_node->name) > 0)
    {
        new_node->next = *head;
        *head = new_node;
    }
    else
    {
        current = *head;
        while (current->next!=NULL && strcmp(current->next->name, new_node->name) < 0)
        {
            current = current->next;
        }
        new_node->next = current->next;
        current->next = new_node;
    }
}
int main()
{

    struct catalog* head = NULL;
    sortedInsert(&head, "Kappa");
    sortedInsert(&head, "Pxntry");
    sortedInsert(&head, "Sdafscx");
    sortedInsert(&head, "Saxzxc");
    sortedInsert(&head, "Zsdas");
    sortedInsert(&head, "Zzzzzzzz");
    sortedInsert(&head, "Country");
    sortedBookInsert(&head, "Country", "PKP", 11111, "Germany");
    sortedBookInsert(&head, "Country", "Polacy", 11112, "Italy");
    sortedBookInsert(&head, "Country", "Bus", 11234, "France");
    sortedBookInsert(&head, "Country", "Poltics", 14111, "Russia");
    printList(head);
    findbookcatalog(&head, 11112); // this will "eat" "Bus" and "PKP", so books that appear before Polacy
    printf("\n");
    printList(head);
    return 0;
}

Он должен печатать мои вложенные списки два раза, два раза одинаково, но он удаляет все книги, которые находятся до поиска книги.

Результат:

Country  Bus  11234  France
Country  PKP  11111  Germany
Country  Polacy  11112  Italy
Country  Poltics  14111  Russia
Kappa
Pxntry
Saxzxc
Sdafscx
Zsdas
Zzzzzzzz

Country  Polacy  11112  Italy
Country  Poltics  14111  Russia
Kappa
Pxntry
Saxzxc
Sdafscx
Zsdas
Zzzzzzzz

1 Ответ

1 голос
/ 03 июня 2019

Этот код удаляет книги из списка:

current->firstbook = current->firstbook->new;

Вы, вероятно, хотели использовать что-то вроде этого:

current_book = current->firstbook;
while (current_book) {
    if (current_book->number == number) {
        return current_book;
    }
    current_book = current_book->new;
}

Я изменил эту функцию, которая исправляет вашу текущую проблему:

struct catalog *findbookcatalog(struct catalog** head, int number) //function that deletes a book when used
{
    struct catalog* current;
    current = *head;
    struct book *current_book;
    while(current != NULL)
    {
        current_book = current->firstbook;
        while(current_book != NULL)
        {
            if(current_book->number == number)
            {
                return current;
            }
            current_book = current_book->new;
        }
        current = current->next;
    }
    return NULL;
}

Я также изменил эту функцию. У него та же проблема, вы просто еще не тестировали.

struct book *findbook(struct catalog** head, int number)
{
    struct catalog* current = findbookcatalog(head, number);
    struct book* booklocation;
    if (current != NULL) {
        booklocation = current->firstbook;
        while(booklocation != NULL)
        {
            if(booklocation->number == number)
            {
                return booklocation;
            }
            booklocation = booklocation->new;
        }
    }
    return NULL;
}
...