Search code examples
c++sortingbubble-sort

Sorting book titles alphabetically issue


This is part of a homework assignment that I am almost done with. Basically I have to use an array of structs to store a library of books by title and author. I have the code working and currently it does in fact store and then sort alphabetically. If you show all books or search by title it prints alphabetically by the title, and the same is for search by author except it prints alphabetically by the author(s). An issue I encountered is that for some reason the books and their authors got switched around. So if you search for book x with author x, you instead get book x with author y.

On the list of books below an example would be:

C++ Programming: From Problem Analysis... (Malik) // Correct author

but instead returns something like:

C++ Programming: From Problem Analysis... (Brandon) // Wrong author

#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>

using namespace std;

// struct/variables
struct Book {
    string title;
    string author;
};

const int ARRAY_SIZE = 1000;
Book books [ARRAY_SIZE];
string pathname;
ifstream library;

// global variables
int LoadData();
void ShowAll(int count);
void ShowBooksByAuthor(int count, string name);
void ShowBooksByTitle(int count, string title);
void sortByTitle(int count, string title);
void sortByAuthor(int count, string author);

int main()
{
    // init vars
    int count = 0;
    char selector = 'q', yesNoAnswer = 'n';
    string name;
    string title;

    // prompt user and get file path
    cout << "Welcome to Forrest's Library Database." << endl;
    cout << "Please enter the name of the backup file: ";
    getline(cin, pathname);
    LoadData();
    count = LoadData();
    cout  << count << " records loaded successfully." << endl;

    // build 'case' menu 
    do 
    {
        cout << endl << "\t(S)how All, Search (A)uthor, Search (T)itle, (Q)uit: "; //menu options
        cin >> selector;
        selector = toupper(selector);
        switch(selector)
        {
            case 'S': // show all the book titles and authors
                sortByTitle(count, title);
                if (count <= 0)
                    cout << "No counts found!\n";
                else
                    ShowAll(count);
                break;
            case 'A': // search by author name 
                sortByAuthor(count, name);
                cout << "bookAuthor: ";
                cin.ignore();
                getline(cin, name);
                if (count <= 0)
                    cout << "No records found!\n";
                else
                    ShowBooksByAuthor(count, name); 
                break;
            case 'T': // search by book title
                sortByTitle(count, title);
                cout << "bookTitle: ";
                cin.ignore();
                getline(cin, title);
                if (count <= 0)
                    cout << "No records found!\n";
                else
                    ShowBooksByTitle(count, title);      
                break; 
        }
    }
    while (selector != 'q' && selector != 'Q'); // the condition that will break the do loop and exit
    return 0;
}
int LoadData() // loads the titles and authors into two arrays
{
    int count = 0;
    int i = 0;

    library.open(pathname);
    ifstream library(pathname);

    if (!library)
    {
        cout << "Cannot open backup file" << endl;
        return 0;
    }

    while (!library.eof())
    {

        getline(library, books[count].title);
        getline(library, books[count].author);

        count++;
    }
    return count;

}
void ShowAll(int count) // displays all book titles beside the author names
{

    for (int i = 0; i < count; i++)
    {
       cout << books[i].title << " " << "(" << books[i].author << ")" << endl;
    }

}

void ShowBooksByAuthor(int count, string name) // displays all books by author
{
    int j = 0;

    for (int i = 0; i < count; i++)
    {
        if(books[i].author.find(name) < 100) 
        {
            cout << books[i].title << " " << "(" << books[i].author << ")" << endl;
            j++;
        }
    }
    cout << j << " records found";
}

void ShowBooksByTitle(int count, string title) // shows all books by title
{
    int j = 0;

    for (int i = 0; i < count; i++)
    {
        if(books[i].title.find(title) < 100)
        {
            cout << books[i].title << " " << "(" << books[i].author << ")" << endl;
            j++;
        }
    }
    cout << j << " records found";
}

void sortByTitle(int count, string title) {
    string temp;

    for (int i = 0; i < count; i++) {
        for(int j = 0; j < count - i; j++) {
            if (books[j].title > books[j + 1].title) {
                temp = books[j].title;
                books[j].title = books[j + 1].title;
                books[j + 1].title = temp;
            }
        }
    }
}

void sortByAuthor(int count, string name) {
    string temp;

    for (int i = 0; i < count; i++) {
        for(int j = 0; j < count - i; j++) {
            if (books[j].author > books[j + 1].author) {
                temp = books[j].author;
                books[j].author = books[j + 1].author;
                books[j + 1].author = temp;
            }
        }
    }
}

Here's a list of the books and their authors that I'm using. They just need to be copied and pasted into a .txt file (just remove the bullet points. It should all look the same as it's posted here just without them). They descend by book then author(s) then book then author(s).

  • Objects First with Java
  • Barnes and Kolling
  • Game Development Essentials
  • Novak
  • The Game Maker's Apprentice
  • Overmars
  • C++ Programming: From Problem Analysis...
  • Malik
  • C++ Programming Lab Manual
  • Scholl
  • Beginning LINUX Programming
  • Stones and Matthew
  • C++ Programming: Program Design Including...
  • D. S. Malik
  • C++ How to Program
  • Deitel and Deitel
  • Programming and Problem Solving with C++
  • Dale, Weems, Headington
  • Game Character Development with Maya
  • Ward
  • Developing Games in Java
  • Brackeen
  • C# Programming
  • Harvey, Robinson, Templeman, Watson
  • Java Programming
  • Farrell
  • Audio for Games
  • Brandon

Thank you to everyone who can help me solve my issue!


Solution

  • On first glance, it looks like you're leaving Book objects in the same position in the array, and just swapping the titles or authors (depending on the sort function) and leaving the remaining member the same.

    You should be swapping the objects themselves e.g.:

    void sortByAuthor(int count, string name) {
        Book temp; //Book instance instead of string
    
        for (int i = 0; i < count; i++) {
            for(int j = 0; j < count - i; j++) {
                if (books[j].author > books[j + 1].author) {
                    //swapping the instances themselves, but still comparing by the member.
                    temp = books[j];
                    books[j] = books[j + 1];
                    books[j + 1] = temp;
                }
            }
        }
    }
    

    Same for sorting by title.