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).
Thank you to everyone who can help me solve my issue!
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.