I understand how to search and sort an array of int type. However I am confused how to sort/ search an array of object's in which I sort/search by a string in the object. (alphabetically) Here is the code I have so far, I want to search and sort the array by the author's last name:

#include <iostream>
using namespace std;
#include <string>
#include "Book.h"


void displayMenu();

int main()
{
	const int SIZE = 5;
	Book bookList[SIZE];
	string locTitle;
	string locLname;
	string locFname;
	int locYear = 0;
	int choice = 1;
	
	while (choice != 5)
	{
	displayMenu();
	cin >> choice;

	
	if (choice == 1)
	{
		int location = 0;
		for (int x = location; x < location + 1; x++)
		{	
			cout << "Enter the Title: ";
			cin >> locTitle;
			cout << "Enter the author's last name: " ;
			cin >> locLname;
			cout << "Enter the author's first name: " ;
			cin >> locFname;
			cout << "Enter the year of publication for the book: " ;
			cin >> locYear;
			
			cout << "Enter the location of the book, which you would like to overwrite: ";
			cin >> location;
			bookList[location - 1].setTitle(locTitle);
			bookList[location - 1].setAuthor(locLname, locFname);
			bookList[location - 1].setYear(locYear);
		}
		
	}

	if (choice == 2)
	{
		for (int r = 0; r < SIZE; r++)
		{
			cout << "Title: " << bookList[r].getTitle() << endl;
			cout << "Author Last Name: " << bookList[r].getAuthorLastName() << endl;
			cout << "Author First Name: " << bookList[r].getAuthorFirstName() << endl;
			cout << "Year: " <<bookList[r].getYear() << endl;
			cout << endl;
		}
	}
	
	if (choice == 3)
	{
		
    
	}
	
	if (choice == 4)
	{
		
	}
	
	}
			
		return 0;
}

void displayMenu()
{
	cout << "Menu" << endl;
	cout << "1. Add a book to the list. " << endl;
	cout << "2. Print out the current list of books. " << endl;
	cout << "3. Sort the list by the author's last name. " << endl;
	cout << "4. Search for books by author.  " << endl;
	cout << "5. Exit the program. " << endl;
	cout << "Enter your choice: ";
}

----------------------------------------
Book.cpp

#include <iostream>
using namespace std;
#include <string>
#include "Book.h"
#include <ostream>

Book::Book()
{
	title = "Unknown";
	authorLastName = "Doe";
	authorFirstName = "John";
	year = 1500;
}

Book::Book(string ti, string ln, string fn, int yr)
{
	title = ti;
	authorLastName = ln;
	authorFirstName = fn;
	year = yr;
}

Book::Book(const Book& source)
{
	title = source.title;
	authorLastName = source.authorLastName;
	authorFirstName = source.authorFirstName;
	year = source.year;
}

void Book::setTitle(string ti)
{
	title = ti;
}

void Book::setAuthor(string ln, string fn)
{
	authorLastName = ln;
	authorFirstName = fn;
}



bool Book::setYear(int yr)
{
	bool result = false;
	if (year >= 1500 && year <= 2009)
	{	result = true;
		year = yr;
	}
	else
		result = false;

	return result;
}

string Book::getTitle()
{
	return title;
}

string Book::getAuthorLastName()
{
	return authorLastName;
}

string Book::getAuthorFirstName()
{
	return authorFirstName;
}

int Book::getYear()
{
	return year;
}
bool Book::operator==(const Book & right)
{
	if(title == right.title && authorLastName == right.authorLastName)
		return true;
	else
		return false;
}

-------------------------------------------
book.h

#include <ostream>
using namespace std;

class Book
{
	private:
		string title;		
		string authorLastName;
		string authorFirstName;
		int year;

	public:
		Book();	// The default constructor
			// The default constructor sets the title to “unknown”,
			// the author to “John Doe”, and the year to 0
		Book(string, string, string, int);	
		Book(const Book& source);	// The copy constructor

		// Mutator functions
		void setTitle(string);
		void setAuthor(string, string);
		bool setYear(int);		// A valid year is any year from
								// 1500 and 2009. The function will set a valid year to the year
								// member variable and return true. It not do the set on an invalid
								// year, and return false.

		// Accessor functions
		string getTitle();
		string getAuthorLastName();
		string getAuthorFirstName();
		int getYear();
		bool operator==(const Book & right);



	

};

Recommended Answers

All 7 Replies

You'll do it pretty much the same as with plain old int's. A search function must compare the comparable element from the book object with the target sought. So if you ask the user for an author, stored in a string, compare that to the string your getAuthor( ) method returns. The string type already supports the == operator. Similarly, when sorting, you can access the author strings of two books and compare them with > or <. Remember that when you do the exchanges in the sort, you're exchanging entire objects. Your copy constructor looks fine for that.

Give it a shot and show your work. We'll go from there.

Ok, thank you am I getting closer with this...

void selectionSort(Book bookList[], int SIZE)
{
	int startScan, minIndex;
	string strName;
	for (startScan = 0; startScan < (SIZE - 1); startScan++)
	{
		minIndex = startScan;
		strName = bookList[startScan].getAuthorLastName();
		for(int index = startScan + 1; index < SIZE; index++)
		{
			if (bookList[index].getAuthorLastName() < strName)
			{
				strName = bookList[index].getAuthorLastName();
				minIndex = index;
			}
		}
		bookList[minIndex].getAuthorLastName() = bookList[startScan].getAuthorLastName();
		bookList[startScan].getAuthorLastName() = strName;
	}
}

Getting close. The comparison loop looks good, but the exchange needs work.

First, any exchange is going to be a three way assignment action.
Consider the following:

int a = 5;
  int b = 10;
  int temp;
  
  temp = a;
  a = b;
  b = temp;

When this is done, a holds the original value of b, b holds the original value of a, and we don't care what temp is left with.

In your problem, when you do the exchange, don't move authors around, as you'll now have wrong authors with the books!
Do an exchange of full book objects.

An, you wouldn't be changing anything with a xxx.getAuthorLastName( ) = yyy.getAuthorLastName( ) - you'd need to use the xxx.setAuthorName( ln, fn) format.

closer???

void selectionSort(Book bookList[], int SIZE)
{
	int a, b;
	Book temp;
	for (a = 0; a < (SIZE - 1); a++)
	{
		bookList[b] = bookList[a];
		temp = bookList[a];
		for(int index = a + 1; index < SIZE; index++)
		{
			if (bookList[index].getAuthorLastName() < temp.getAuthorLastName())
			{
				temp = bookList[index];
				b = index;
			}
		}
		bookList[b] = bookList[a];
		bookList[a] = temp;
	}
}

Go back to the simple selection sort

void selectionSort(int list[], int SIZE)
{
	int swp_index; //tracks smallest found value
	int temp;

	for (a = 0; a < (SIZE - 1); a++)
	{
		swp_index = a;
		for(int index = a + 1; index < SIZE; index++)
		{
			if (list[index] < list[swp_index] )
			{
				swp_index = index;
			}
		}

		temp = list[a];
		list[a] = list[swp_index];
		list[swp_index] = temp;
	}
}

To sort your list of Book objects, you don't need to store a copy of any book for comparisons, just use the getAuthor method on both sides. In the exchange step, you must do the three way exchange.

What is index b pointing to? You never initialize the value b.

Follow the model that works, substituting your data item for the generic "list" above.

OK, I think I have the sort... Now im having problems with the search, if I cannot get it to return the index... It returns -1 every time....

#include <iostream>
using namespace std;
#include <string>
#include "Book.h"


void displayMenu();
void selectionSort(Book[], int);
int search(Book[], string, int);

int main()
{
	const int SIZE = 100;
	Book bookList[SIZE];
	string locTitle;
	string locLname;
	string locFname;
	int locYear = 0;
	int choice = 1;
	
	while (choice != 5)
	{
		displayMenu();
		cin >> choice;
		
		
		if (choice == 1)
		{
			int location = 0;
			for (int x = 0 ; x < 1 ; x++)
			{	
				cout << "Enter the Title: ";
				cin >> locTitle;
				cout << "Enter the author's last name: " ;
				cin >> locLname;
				cout << "Enter the author's first name: " ;
				cin >> locFname;
				cout << "Enter the year of publication for the book: " ;
				cin >> locYear;
				
				cout << "Enter the location of the book, which you would like to overwrite: ";
				cin >> location;
				bookList[location - 1].setTitle(locTitle);
				bookList[location - 1].setAuthor(locLname, locFname);
				bookList[location - 1].setYear(locYear);
			}
			
		}
		
		if (choice == 2)
		{
			for (int r = 0; r < SIZE; r++)
			{
				cout << "Title: " << bookList[r].getTitle() << endl;
				cout << "Author Last Name: " << bookList[r].getAuthorLastName() << endl;
				cout << "Author First Name: " << bookList[r].getAuthorFirstName() << endl;
				cout << "Year: " <<bookList[r].getYear() << endl;
				cout << " ---------------------------------- " << endl;
				cout << endl;
				
			}
			cout << " ---------------------------------- " << endl;
			cout << " ---------------------------------- " << endl;
		}
		
		if (choice == 3)
		{
			selectionSort(bookList, SIZE);
		}
		
		if (choice == 4)
		{
			int results = 0;
			string searchTarget;
			cout<< "Enter the author to search for: ";
			cin >> searchTarget;
			results = search(bookList, searchTarget, SIZE);
			
			
			if (results = -1)
			{
				cout << "Entry Not Found!" << endl;
			}
			else
			{
				cout << "Results" << endl;
				cout << "Title: " << bookList[results + 1].getTitle() << endl;
				cout << "Author Last Name: " << bookList[results + 1].getAuthorLastName() << endl;
				cout << "Author First Name: " << bookList[results + 1].getAuthorFirstName() << endl;
				cout << "Year: " <<bookList[results + 1].getYear() << endl;
				cout << " ---------------------------------- " << endl;
				cout << endl;
			}
			
		}
	}

	
	return 0;
}

void displayMenu()
{
	cout << "Menu" << endl;
	cout << "1. Add a book to the list. " << endl;
	cout << "2. Print out the current list of books. " << endl;
	cout << "3. Sort the list by the author's last name. " << endl;
	cout << "4. Search for books by author.  " << endl;
	cout << "5. Exit the program. " << endl;
	cout << "Enter your choice: ";
}

void selectionSort(Book list[], int SIZE)
{
	int swp_index = 0; //tracks smallest found value
	Book temp;
	
	for (int a = 0; a < (SIZE - 1); a++)
	{
		swp_index = a;
		for(int index = a + 1; index < SIZE; index++)
		{
			if (list[index].getAuthorLastName() < list[swp_index].getAuthorLastName() )
			{
				swp_index = index;
			}
		}
		
		temp = list[a];
		list[a] = list[swp_index];
		list[swp_index] = temp;
	}
}

int search(Book list[], string value, int size)// method to find index of specified element
{
	int index = 0;
	int position = -1;
	bool found = false;
	
	while(index < size && !found)
	{
		if (list[index].getAuthorLastName() == value)
		{
			found = true;
			position = index;
		}
		index++;
	}
	return position;
}

I thought you fixed this

if (results = -1)

(ed - oops sorry, saw this same problem in a different thread. Still, watch out for that gotcha!)

A couple other comments:
Use the if...else if construct in your decision in main( ).
Use getline( ) to read in titles and names rather than cin >> -- so you can have multiword titles and, in some case, names.

Keep track of how many books have been added, pass that number as the size parameter to function, and as limit on other loops. Don't ask user where in array to put new book, just add any new book to end. Otherwise, in real use you'll end up with data scattered all around, for no good reason.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.