我的功能之一是不小心从列表中删除了元素

One of my functions is accidentally deleting elements from list

我正在尝试制作一个 "library",其中有按字母顺序排序的目录,并且每个目录都有也按字母顺序排列的书籍。作为 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

此代码正在从列表中删除书籍:

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;
}