-1

So in my current program I am tasked to store a vector of branches. These branches contain a string name, and a pointer to a node.

These nodes store a book, which has an author name, a title, and the number of copies.

Overall, this should create the data structure of a linked list.

Currently I am attempting to write a program to delete or "check out" a certain book from a branch.

After adding these books to the branch AO.

Stan Moon

Bill Sun

Chris Ground

Lan Sky

I attempt to check out the book Ground by Chris. If the book has multiple copies, (which in this case it doesn't) it just decreases the amount of copies by one. If it only has one copy, then it deletes it, sets the object that previously pointed to it to the object that Ground pointed to, then delete the link between Ground and its next.

However, for some reason after performing this function, nothing about my linked list changes. Is there a reason for this?

Thanks in advance!

#include "Library.h"
#include <vector>
#include <string>
#include <iostream>

using namespace std;
int total;
int index;

Library::Library()
{

}

struct Node //Has everything in it
{
    string author;
    string title;
    int copies;
    Node* next;
};

struct Branch // Stores just the branch, and a point to the node with information in it.
{
    string b_name;
    Node* next;
};

vector<Branch*> lib;

void Library::start()
{
    int choice = 0;
    do
    {
        cout << "Please select a choice." << endl;
        cout << " " << endl;
        cout << "1. Create a branch and insert its books" << endl;
        cout << "2. Given an author name, a title and a branch name, CHECKOUT that book from the branch." << endl;
        cout << "3. Given an author name, title and a branch name, RETURN that book to the branch." << endl;
        cout << "4. Given an author name, title and branch name, FIND the number of copies of that book are available in that branch." << endl;
        cout << "5. PRINT all books contained in a branch." << endl;
        cout << "6. Exit the program." << endl;

        cin >> choice;

        switch (choice)
        {
        case 1:
            insert();
            break;

        case 2:
            checkout();
            break;

        case 3:
            Return();
            break;

        case 4:
            find();
            break;

        case 5:
            printAll();
            break;

            // TODO: other choises
        }
    } while (choice != 6);
}

void Library::insert()
{
    string br;
    string auth;
    string titl;

    cout << "What is the name of the branch?" << endl;
    cin >> br;

    Branch *branch = new Branch();
    branch->b_name = br;
    lib.push_back(branch);
    Node* lastNode = nullptr;

    do
    {
        cout << "What is the author and title of the book?" << endl;
        cin >> auth >> titl;
        if (auth == "NONE" && titl == "NONE") break;

        Node *book = new Node();
        book->author = auth;
        book->title = titl;
        book->copies++;
        if (lastNode == nullptr) {
            branch->next = book;
        }
        else {
            lastNode->next = book;
        }
        lastNode = book;
    } while (auth != "NONE" && titl != "NONE");

    start();
}

void Library::checkout()
{
    string auth;
    string titl;
    string bran;
    bool success = false;

    cout << "Insert author, title and branch" << endl;
    cin >> auth >> titl >> bran;

    for (unsigned int i = 0; i < lib.size(); i++)
    {
            auto* branch = lib[i];
            auto* node = branch->next;
            Node* previous = nullptr;

            while (node)
            {
                if (node->author == auth && node->title == titl && branch->b_name == bran)
                    if (node->copies > 1) node->copies--; success = true;  break;
                if (node->copies == 1)
                {
                    previous->next = node->next;
                    node->next = nullptr;
                    success = true;
                    break;
                }

                if (!success)
                {
                    previous = node;
                    node = node->next;
                }

            }
            if (success)
            {
                cout << "Complete!" << endl;
                cout << "" << endl;
            }


    }
    start();
}
Granzo
  • 59
  • 1
  • 7
  • Not the cause of this particular problem, but your functions should not call `start()`, they should just return. – molbdnilo May 04 '18 at 08:12
  • Try fixing the indention. Add curly brackets where missing. (for example after if(!success) ) – kiloalphaindia May 04 '18 at 08:25
  • @molbdnilo Well, isn't it determinate by declaring its value equal to node then incrementing node? However, I can see how this would cause an issue if it were the first book in the linked list. Correct me if i'm wrong. – Granzo May 04 '18 at 08:26
  • 1
    Don't write your own linked list. Use `std::list`. – Raedwald May 04 '18 at 08:31
  • Possible duplicate of https://stackoverflow.com/questions/25385173/what-is-a-debugger-and-how-can-it-help-me-diagnose-problems – Raedwald May 04 '18 at 08:32
  • There are many issues. Calling `start()` at the end of each of the function may seem to work, but the approach is totally wrong, wou will end up with a stackoverflow after some time. You have unreachable code in the `checkout`function, compile with all warnings enabled (`-Wall`). – Jabberwocky May 04 '18 at 08:32
  • The check for the author and name applies only to the branch with `copies>1`. I guess your code removes some node, just different one than you expect. Also, you should try to make your code a [Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve). You would likely discover the problem in the process. – Frax May 04 '18 at 08:48
  • Or, to put it the other way: don't try to write the whole thing at once. Write working list, then put it inside bigger program, not the other way around. – Frax May 04 '18 at 08:51
  • @Frax Thank you for the advice! I will definitely take this into account when moving forward. I'm still relatively new to coding, so I always attempt to write a great deal at once, then check. I can see it's a bad idea. – Granzo May 04 '18 at 08:55

1 Answers1

1

What about this:

    void Library::checkout()
{
    string auth;
    string titl;
    string bran;
    bool success = false;

    cout << "Insert author, title and branch" << endl;
    cin >> auth >> titl >> bran;

    for (unsigned int i = 0; i < lib.size(); i++)
    {
        auto* branch = lib[i];
        auto* node = branch->next;
        Node* previous = nullptr;

        while (node)
        {
            if (node->author == auth && node->title == titl && branch->b_name == bran)
            {
                if (node->copies > 1)
                {
                    node->copies--;
                    success = true; 
                    break;
                }
                else
                {
                    if (previous)
                    {
                        previous->next = node->next;
                    }
                    else
                    {
                        branch->next = node->next;
                    }
                    delete node;
                    success = true;
                    break;
                }
            }
            previous = node;
            node = node->next;
        }
        if (success)
        {
            cout << "Complete!" << endl;
            cout << "" << endl;
        }
    }
    //  no need to call start() as start() has a do/while loop
    // start();

}

Edit: fix wrong placement of delete condition

kiloalphaindia
  • 561
  • 3
  • 7