我在 C 代码中的错误是什么?这是一个需要使用 FILE 处理和 BST 的图书馆目录

What are my errors in this code in C? It's a library catalog that needs to use FILE handling and BST

1) 我坚持插入和显示用户输入。我很困惑何时使用 fwrite,无论是在 addRecord 函数内还是在 insert 函数内。

2)输入后写还是插入后写?

无论如何,我的代码是这样的:

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

struct book{
    char title[30];
    char author[20];
    char isbn[14]; 
    char genre[10];
    char publisher[30];
    int year;
    char synopsis[150];
    struct book *left;
    struct book *right;
};

typedef struct book catalog;
catalog *root;
FILE *fx,*fy;
int structsize=sizeof(catalog);


void addBooks(); 
void removeBooks(); 
void modify(); 
void searchBook(); 
void perTitle(); 
void perAuthor(); 
void perISBN(); 
void perGenre(); 
void displayCatalog(catalog *root); 
int ifexists(char *x); 
void insert(catalog *root,catalog *x);
catalog remove(catalog *root,catalog *x);
void menu();
void gotoxy(int x,int y);

void main(){
    root=NULL;

    fx=fopen("CAT.dat","rb+");
    if(fx==NULL){
        fx=fopen("CAT.dat","wb+");
        if(fx==NULL){
            gotoxy(22,10);
            printf("No records to show...");
            getch();
            menu();
        }
    }

    menu();
}

void menu(){
    int choice;

    system("cls");
    gotoxy(22,5);
    printf("----------WELCOME TO THE CARD CATALOG----------");
    gotoxy(22,7);
    printf("1] Add a book");
    gotoxy(22,8);
    printf("2] Remove a book");
    gotoxy(22,9);
    printf("3] Modify a book");
    gotoxy(22,10);
    printf("4] Search a book");
    gotoxy(22,11);
    printf("5] Display the catalog");
    gotoxy(22,12);
    printf("6] Exit");

    gotoxy(22,14);
    printf("Enter your choice: ");
    scanf("%d",&choice);

    switch(choice){
    case 1: addBooks();
        break;
    case 2: removeBooks();
        break;
    case 3: modify();
        break;
    case 4: searchBook();
        break;
    case 5: displayCatalog(root);
        break;
    case 6: exit(0);
    }
}

void addBooks(){
    char n;
    catalog *ptr;
    ptr=(catalog*)malloc(sizeof(catalog));
    fx=fopen("CAT.dat","ab+");
    fseek(fx,0,SEEK_END);

    system("cls");fflush(stdin);
    gotoxy(22,8);
    printf("Title: ");
    scanf("%[^\n]s",ptr->title);fflush(stdin);
    gotoxy(22,9);
    printf("Author: ");
    scanf("%[^\n]s",ptr->author);fflush(stdin);
    gotoxy(22,10);
    printf("Genre: ");
    scanf("%[^\n]s",ptr->genre);fflush(stdin);
    gotoxy(22,11);
    printf("ISBN: ");
    scanf("%[^\n]s",ptr->isbn);fflush(stdin);
    gotoxy(22,12);
    printf("Publisher: ");
    scanf("%[^\n]s",ptr->publisher);fflush(stdin);
    gotoxy(22,13);
    printf("Year: ");
    scanf("%d",&ptr->year);fflush(stdin);
    gotoxy(22,14);
    printf("Synopsis: ");
    scanf("%[^\n]s",ptr->synopsis);fflush(stdin);
    ptr->left=NULL;
    ptr->right=NULL;

    if(root==NULL){
        root=ptr;
    } else {
        insert(root,ptr);
    }

    gotoxy(22,18);
    printf("Add another (y/n)? ");
    scanf("%c",&n);
    if(n=='y' || n=='Y'){
        addBooks();
    }

    fclose(fx);
    getch();
    menu();
}

void insert(catalog *root,catalog *x){
    fx=fopen("CAT.dat","ab+");
    fseek(fx,0,SEEK_END);

    if((x->isbn) < (root->isbn)){
        if(root->left==NULL){
            root->left=x;
        } else {
            insert(root->left,x);
        }
    }

    if((x->isbn) > (root->isbn)){
        if(root->right==NULL){
            root->right=x;
        } else {
            insert(root->right,x);
        }
    }

    fwrite(&x,structsize,1,fx);

    fclose(fx);
    getch();
}

void removeBooks(){
    catalog *ptr,*temp;
    int x;
    char title[20],y;

    system("cls");

    if(root==NULL){
        gotoxy(22,10);
        printf("No records to show...");
        getch();
        menu();
    }

    gotoxy(22,10);
    printf("Enter title of book to delete: ");
    scanf("%s",title);

    ptr=root;
    while(ptr!=NULL){
        if(strcmp(ptr->title,title)==0){
            gotoxy(22,11);
            printf("The book is in the catalog.");
            gotoxy(22,12);
            printf("Title: %s",root->title);
            gotoxy(22,13);
            printf("Author: %s",root->author);
        } else {
            gotoxy(22,11);
            printf("No book with that title in the catalog.");
            getch();
            menu();
        }

        if(strcmp(ptr->title,title)==0){
            gotoxy(22,14);
            printf("Remove book record? (y/n) ");
            if(getch()=='y'){
                remove(root,ptr);
                menu();
            } else {
                menu();
            }
        }
    }
}

catalog remove(catalog *root,catalog *x){
    catalog *temp;
    char y;

    if(x==root){
        temp=root;
        free(temp);
        root=NULL;
    } else if(x->isbn < root->isbn){
        *root->left=remove(root->left,x);
    } else if(x->isbn > root->isbn){
        *root->right=remove(root->right,x);
    } else if(root==NULL){
        gotoxy(22,10);
        printf("Nothing to remove...");
        getch();
        menu();
    }

    printf("The book has been removed.");
    printf("Remove another book? (y/n) ");
    scanf("%c",&y);

    return *x;
}

void modify(){
    catalog *ptr;
    int num;
    char title[20];

    system("cls");

    if(root==NULL){
        gotoxy(22,10);
        printf("No records exist...");
        getch();
        menu();
    }

    printf("Enter title of book to be modified: ");
    scanf("%s",title);

    ptr=root;
    while(ptr!=NULL){
        if(strcmp(ptr->title,title)==0){
            printf("Input new information.");
            printf("Title: ");
            scanf("%s",root->title);
            printf("Author: ");
            scanf("%s",root->author);
            printf("ISBN: ");
            scanf("%d",root->isbn);
            printf("Publisher: ");
            scanf("%s",root->publisher);
            printf("Year: ");
            scanf("%d",root->year);
            printf("Synopsis: ");
            scanf("%s",root->synopsis);

            printf("The book's information has been modified.");
        } else {
            printf("No book found.");
            break;
        }
    }

    getch();
    menu();
}

void searchBook(){
    int choice;
    char title[20], author[20];
    int num;

    system("cls");

    if(root==NULL){
        printf("No records to show...");
        getch();
        menu();
    }

    gotoxy(22,10);
    printf("-----SEARCH A BOOK-----");
    gotoxy(22,12);
    printf("1] By title");
    gotoxy(22,13);
    printf("2] By author");
    gotoxy(22,14);
    printf("3] By ISBN");
    gotoxy(22,15);
    printf("4] Back to menu");
    gotoxy(22,18);
    printf("Enter your choice: ");
    scanf("%d",&choice);

    switch(choice){
    case 1: perTitle();
        break;
    case 2: perAuthor();
        break;
    case 3: perISBN();
        break;
    case 4: perGenre();
        break;
    case 5: menu();
    }
}

void perTitle(){
    catalog *ptr;
    char title[20], temp[20], ans;

    system("cls");
    gotoxy(22,15);
    printf("Enter book title: ");
    scanf("%s",title);fflush(stdin);

    ptr=root;
    while(ptr!=NULL){
        while(strcpy(temp,ptr->title)){
            if(strcmp(temp,title)==0){
                system("cls");
                gotoxy(22,10);
                printf("That book is in the catalog.");
                gotoxy(22,11);
                printf("Title: %s",ptr->title);
                gotoxy(22,12);
                printf("Author: %s",ptr->author);
                gotoxy(22,13);
                printf("ISBN: %d",ptr->isbn);
                gotoxy(22,14);
                printf("Genre: %s",ptr->genre);
                gotoxy(22,15);
                printf("Publisher: %s",ptr->publisher);
                gotoxy(22,16);
                printf("Year: %d",ptr->year);
                gotoxy(22,17);
                printf("Synopsis: %s",ptr->synopsis);fflush(stdout);
                break;
            } else {
                gotoxy(22,10);
                printf("No records to show...");
            }
        }

        printf("Try another? (y/n) ");
        scanf("%c",&ans);fflush(stdin);

        switch(ans){
        case 'y': searchBook();
            break;
        case 'n': menu();
        }
    }
}

void perAuthor(){
        catalog *ptr;
        char author[20],au[20],ans;

        system("cls");
        gotoxy(22,15);
        printf("Enter author's name: ");
        scanf("%s",author);fflush(stdin);

        ptr=root;

        while(ptr!=NULL){
        while(strcpy(au,ptr->title)){
            if(strcmp(au,author)==0){
            system("cls");
            gotoxy(22,10);
            printf("That book is in the catalog.");
            gotoxy(22,11);
            printf("Title: %s",ptr->title);
            gotoxy(22,12);
            printf("Author: %s",ptr->author);
            gotoxy(22,13);
            printf("ISBN: %d",ptr->isbn);
            gotoxy(22,14);
            printf("Genre: %s",ptr->genre);
            gotoxy(22,15);
            printf("Publisher: %s",ptr->publisher);
            gotoxy(22,16);
            printf("Year: %d",ptr->year);
            gotoxy(22,17);
            printf("Synopsis: %s",ptr->synopsis);
        } else {
            gotoxy(22,10);
            printf("No records to show...");
        }

        printf("Try another? (y/n) ");
        scanf("%c",&ans);

        switch(ans){
        case 'y': searchBook();
            break;
        case 'n': menu();
            }
        }
    }
}

void perISBN(){
        catalog *ptr;
        char isbn[20];
        char ans;

        system("cls");
        gotoxy(22,15);
        printf("Enter book ISBN: ");
        scanf("%s",isbn);fflush(stdin);

        ptr=root;
        while(ptr->isbn==isbn){
            ptr=ptr->left;
            if(ptr==NULL)
                menu();
        }

        system("cls");
        if(ptr!=NULL){
            gotoxy(22,10);
            printf("That book is in the catalog.");
            gotoxy(22,11);
            printf("Title: %s",ptr->title);
            gotoxy(22,12);
            printf("Author: %s",ptr->author);
            gotoxy(22,13);
            printf("ISBN: %d",ptr->isbn);
            gotoxy(22,14);
            printf("Genre: %s",ptr->genre);
            gotoxy(22,15);
            printf("Publisher: %s",ptr->publisher);
            gotoxy(22,16);
            printf("Year: %d",ptr->year);
            gotoxy(22,17);
            printf("Synopsis: %s",ptr->synopsis);
        } else {
            gotoxy(22,10);
            printf("No records to show...");
        }

        printf("Try another? (y/n) ");
        scanf("%c",&ans);

        if(ans=='y' || ans=='Y'){
            searchBook();
        }

        getch();
        menu();
    }

void perGenre(){
        catalog *ptr;
        char genre[20],ans;
        char gen[10];

        system("cls");
        gotoxy(22,15);
        printf("Enter book title: ");
        scanf("%s",genre);

        ptr=root;
        while(strcmp(ptr->genre,genre)!=0){
            ptr=ptr->left;
            if(ptr==NULL)
                menu();
        }

        system("cls");
        if(ptr!=NULL){
            gotoxy(22,10);
            printf("That book is in the catalog.");
            gotoxy(22,11);
            printf("Title: %s",ptr->title);
            gotoxy(22,12);
            printf("Author: %s",ptr->author);
            gotoxy(22,13);
            printf("ISBN: %d",ptr->isbn);
            gotoxy(22,14);
            printf("Genre: %s",ptr->genre);
            gotoxy(22,15);
            printf("Publisher: %s",ptr->publisher);
            gotoxy(22,16);
            printf("Year: %d",ptr->year);
            gotoxy(22,17);
            printf("Synopsis: %s",ptr->synopsis);
        } else {
            gotoxy(22,10);
            printf("No records to show...");
        }

        printf("Try another? (y/n) ");
        scanf("%c",&ans);

        switch(ans){
        case 'y': searchBook();
            break;
        case 'n': menu();
        }
    }

void displayCatalog(catalog *root){
        catalog *ptr;
        system("cls");
        fx=fopen("CAT.dat","rb+");
        rewind(fx);

        ptr=root;
        while(fread(&ptr,structsize,1,fx)==1){
            if(root->left!=NULL){
                displayCatalog(root->left);
            }
            printf("Title: %s\n",ptr->title);
            printf("Author: %s\n",ptr->author);
            printf("ISBN: %s\n",ptr->isbn);
            printf("Genre: %s\n",ptr->genre);
            printf("Publisher: %s\n",ptr->publisher);
            printf("Year: %d\n",ptr->year);
            printf("Synopsis: %s\n",ptr->synopsis);
            if(root->right!=NULL){
                displayCatalog(root->right);
            }
            break;
        }

        fclose(fx);
        getch();
        menu();
}

void gotoxy(int x,int y){
        COORD coord;
        coord.X=x;
        coord.Y=y;
        SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
    }

1) 您已关闭所有编译器警告,或者您已选择忽略大约 100 个编译器警告。

您应该重新开始,将编译器警告设置为最大值,或至少 4。编写程序,使其在编译时出现零警告。

几个值得注意的错误:

scanf("%d",root->isbn);

isbn 是字符数组,所以这应该是 scanf("%s",root->isbn);

scanf("%d", root->year); 

scanf 需要变量的地址,而不是复制。应该是scanf("%d", &root->year);

您还有许多其他错误,例如在 void modify 中您尝试访问未初始化的指针 ptr

2) 你有这个 gotoxy 功能,它让事情看起来很不错,但你应该删除它,因为你的程序根本无法运行。如果您的程序可以正常运行,那么您可以放回这些修饰函数。

3) 尽量避免使用全局变量。 FILE *fx, *fy; 特意出问题。您有打开的文件句柄,然后您尝试以不同的模式再次打开它们。

catalog *root;没有分配。整个程序似乎都依赖于这个变量,这将无处可去。例如

void perTitle() 
{
    catalog *ptr;
    ...
    ptr = root;
    while (ptr != NULL) 
    {
        while (strcpy(temp, ptr->title)) 
        {
            ...
        }
    }
}

这可能看起来像一个搜索功能,但它只是 while(0){},它什么也做不了。

4) 看来你是在管理文件中的记录,并且还把它们存储在一个链表中。这变得非常混乱。你应该做一个或另一个。我建议您将记录存储在文件中。将它们读入链表。然后在完成后将它们保存到文件中。

5) 使用更多的功能来避免输入同样的东西。例如写一个新函数 showBook

void showBook(catalog *ptr)
{
    printf("Title: %s\n", ptr->title);
    printf("Author: %s\n", ptr->author);
    printf("ISBN: %s\n", ptr->isbn);
    printf("Genre: %s\n", ptr->genre);
    printf("Publisher: %s\n", ptr->publisher);
    printf("Year: %d\n", ptr->year);
    printf("Synopsis: %s\n", ptr->synopsis); 
}

您可以在 perTitle()perAuthor()perISBN()perGenre() 和其他地方重复使用此函数。

6) 初始化数据为零,例子:

catalog *ptr = malloc(sizeof(catalog));
memset(ptr, 0, sizeof(catalog));

从一个小程序开始。添加几个简单的功能,测试一下,添加更多功能。您可能想编写一个单独的测试程序来测试链表。例子

void getBook(catalog *ptr)
{
    printf("Title:\n");
    scanf("%s", ptr->title);
    printf("Author:\n");
    scanf("%s", ptr->author);
    printf("Genre:\n");
    scanf("%s", ptr->genre);
    printf("ISBN:\n");
    scanf("%s", ptr->isbn);
    printf("Publisher:\n");
    scanf("%s", ptr->publisher);
    printf("Year:\n");
    scanf("%d", &ptr->year);
    printf("Synopsis:\n");
    scanf("%s", ptr->synopsis);
}

void addBooks() 
{
    catalog cat;
    memset(&cat, sizeof(catalog), 0);
    getBook(&cat);
    FILE* fx = fopen("CAT.dat", "ab+");
    fseek(fx, 0, SEEK_END);
    fwrite(ptr, structsize, 1, fx);
    fclose(fx);
    printf("Add another (y/n)?\n");

    char n;
    scanf("%c", &n);
    if (n == 'y' || n == 'Y') 
        addBooks();

    _getch();
    menu();
}

void displayCatalog()
{
    system("cls");
    FILE* fx = fopen("CAT.dat", "rb+");
    catalog cat;
    while (fread(&cat, sizeof(catalog), 1, fx) == 1)
    {
        showBook(&cat);
        break;
    }
    fclose(fx);
    _getch();
    menu();
}

void menu() 
{
    int choice;
    system("cls");
    printf("----------WELCOME TO THE CARD CATALOG----------\n");
    printf("1] Add a book\n");
    printf("2] Remove a book\n");
    printf("3] Modify a book\n");
    printf("4] Search a book\n");
    printf("5] Display the catalog\n");
    printf("6] Exit\n");
    printf("Enter your choice: \n");
    scanf("%d", &choice);

    switch (choice) 
    {
    case 1: addBooks(); break;
    case 2: removeBooks(); break;
    case 3: modify(); break;
    case 4: searchBook(); break;
    case 5: displayCatalog(); break;
    case 6: exit(0);
    }
}

int main() 
{
    FILE *f = fopen("CAT.dat", "rb+");
    if (f == NULL)
    {
        f = fopen("CAT.dat", "wb+");
        if (f == NULL)
        {
            printf("Cannot create new file...\n");
            return 0;
        }
    }
    fclose(f);
    menu();
    return 0;
}