0

I need to use BST and file handling but I'm stuck with this one because the displayCatalog function doesn't seem to work.

I want to establish the struct first before I print it to the file. How do I go about this?

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

typedef struct book catalog;
FILE *fx,*fy;

struct book{
    char title[20];
    char author[20];
    int isbn[15];
    char genre[10];
    char publisher[20];
    int year[5];
    char synopsis[100];
    catalog *left;
    catalog *right;
};

catalog *root;

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;

    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 y;
    catalog *ptr;
    ptr=(catalog*)malloc(sizeof(catalog));

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

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

    menu();
}

void insert(catalog *root,catalog *x){
    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);
        }
    }
}

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){
        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],ans;

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

    ptr=root;
    while(strcmp(ptr->title,title)!=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 perAuthor(){
    catalog *ptr;
    char author[20],ans;

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

    ptr=root;
    while(strcmp(ptr->author,author)!=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 perISBN(){
    catalog *ptr;
    int isbn[20];
    char ans;

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

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

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

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

    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");

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

    menu();
    }

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

UPDATE: So I edited A BIT of my code so that it can already display. However, there seems to be a problem with comparing the user input's string and the string from my struct because the perTitle, perAuthor, and perGenre functions won't work. The perISBN works perfectly fine.

Here is how the perTitle() looks now:

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

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

ptr=root;
while(strcmp(ptr->title,title)!=0){
    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();
}

}

Given that I have added a book record into the list, it always displays "Try another (y/n)?"

1 Answers1

0

There are a lot of things wrong in the code (it makes me even wonder that it compiles at all) and your compiler should have uttered a lot of warnings if you would have let it.

I think the main culprit is in the struct, especially in the int parts. int isbn[15] reserves an array of 15 ints and that is not what you want. Any ISBN needs more than one int (assuming 4 bytes per int and 8 bit per byte) so use a string for a start. Just change int to char. Also: int year[5] will make an array for five ints but I'm pretty sure one is more than sufficient (again: assuming 4 bytes per int and 8 bit per byte). So your struct is now

struct book{
    char title[20];
    char author[20];
    char isbn[14]; // 13 digits max. plus NUL
    char genre[10];
    char publisher[20];
    int year;
    char synopsis[100];
    catalog *left;
    catalog *right;
};

NB: the typedef should be placed directly under the struct

You also need to change the way you put the year in:

scanf("%d",&ptr->year);

And the comparing in the insert function needs to be able to compare strings now, so

void insert(catalog *root,catalog *x){
    if(strcmp(x->isbn, root->isbn) < 0){
        if(root->left==NULL){
            root->left=x;
        } else {
            insert(root->left,x);
        }
    }

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

I'm not able to test it without a larger rewrite (I don't have Windows with a compiler) so beware of typos. And there are many more errors in your code so it may still not work, although with different reasons that time.

The tree-traversing is a bit messed up, too

void displayCatalog(catalog *root123){
    catalog *ptr;
    system("cls");
    ptr=root123;
    while(ptr!=NULL){
        if(root123->left != NULL){
           displayCatalog(root123->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(root123->right != NULL){
           displayCatalog(root123->right);
        }
        break;
      }

    menu();
    }
deamentiaemundi
  • 5,502
  • 2
  • 12
  • 20
  • How would I make it so that I can print the whole struct into a file? fprintf doesn't seem to work. – Ruby Sparks Oct 09 '16 at 04:17
  • I had some time to look over it a bit more thoroughly and rewrote it to compile here on Unix. The tree-traversing is a bit messed up, I've added it to my post at the end. Please give it a try. Might still not work because I had to change quite a bit to make it compile. – deamentiaemundi Oct 09 '16 at 04:36
  • Thank you so much! It does display now, however when I type "harry potter", it only displays "harry". Is it possible that the array won't display anything after a whitespace? – Ruby Sparks Oct 09 '16 at 04:46
  • That's a problem of `scanf()` See e.g.: http://stackoverflow.com/questions/1247989/how-do-you-allow-spaces-to-be-entered-using-scanf The first answer describe what you should do and the second one "repairs" `scanf()`. – deamentiaemundi Oct 09 '16 at 04:50
  • Thanks again. I got stuck with the strcmp. How do I copy the string from the struct and the user input string? I have given the perTitle function above as it is. – Ruby Sparks Oct 09 '16 at 08:13
  • `isbn` is the key in the tree and you can find in fast in O(log n) but if you search for *anything* else you have to traverse the *whole* tree. You can do it like you did in the display function and instead of just printing the individual nodes you check for the title. BTW: do not `fflush(stdin)`, do something like e.g.: `while( ( c = getchar()) != '\n');` (I think it's `getch()` in Windows) to get rid of trailing characters. – deamentiaemundi Oct 09 '16 at 14:56