I'm at the very last step for this project, and I'm stuck on what to do. The project is to take an input file containing book info, like this:
A Book on C
Al Kelly and Ira Pohl
Addison-Wesley, Fifth Edition 1998.
0201183994
C How to Program
Paul Deitel and Harvey Deitel
Prentice Hall Sixth Edition 2010
0136123562
And then print it using several options. I'll put all the code here so you can compile and see what each option does. I'm having trouble with option 5, specifically. For option 5, I need to:
- Input more information on each book. I'm required to have two subclasses,
InfoBookRecord
containing the price and author biography, andTypeBookRecord
containing the book genre. - Print the new information using virtual functions. I thought it made sense to make the virtual function in the class
ListRecords
, but the grading key seems to imply I should be using them for the two subclassesInfoBookRecord
andTypeBookRecord
. I can't think of any way to do that.
header.h:
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cassert>
#include <fstream>
#include <algorithm>
using namespace std;
#define TABLE_SIZE 200
class BookRecord{
public:
BookRecord(string input_title, string input_author, string input_publisher, int input_isbn);
string getTitle();
string getAuthor();
string getPublisher();
int getISBN();
private:
string title;
string author;
string publisher;
int isbn;
};
class InfoBookRecord: public BookRecord {
public:
InfoBookRecord(string input_title, string input_author, string input_publisher, int input_isbn, double input_price, string input_authorBio) : BookRecord(input_title,input_author,input_publisher,input_isbn) {
price=input_price;
authorBio=input_authorBio;}
double getPrice();
string getAuthorBio();
private:
double price;
string authorBio;
};
class TypeBookRecord: public BookRecord {
public:
TypeBookRecord(string input_title, string input_author, string input_publisher, int input_isbn, string input_genre) : BookRecord(input_title,input_author,input_publisher,input_isbn){
input_genre.resize(15);
genre=input_genre;}
string getGenre();
private:
string genre;
};
class ListRecords{
public:
ListRecords(char filename[]);
void insertBookInfo(BookRecord record);
//virtual void printBookInfo(int bookISBN);
void printBookInfo(int bookISBN);
void printListByISBN();
void printListByTitle();
BookRecord ** books;
InfoBookRecord ** books2;
TypeBookRecord ** books3;
int line_num;
int k;
string garbage;
};
// problem here
/*
class extraListRecords: public ListRecords{
public:
extraListRecords();
void printBookInfo(int bookISBN){
cout << "testing 1 2 3 " << endl;
}
};*/
BookRecord.cpp:
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cassert>
#include <fstream>
#include <algorithm>
#include "header.h"
using namespace std;
#define TABLE_SIZE 200
BookRecord::BookRecord(string input_title, string input_author, string input_publisher, int input_isbn){
title=input_title;
author=input_author;
publisher=input_publisher;
isbn=input_isbn;
}
string BookRecord::getTitle() {return title;}
string BookRecord::getAuthor() {return author;}
string BookRecord::getPublisher() {return publisher;}
int BookRecord::getISBN() {return isbn;}
double InfoBookRecord::getPrice() {return price;}
string InfoBookRecord::getAuthorBio() {return authorBio;}
string TypeBookRecord::getGenre() {return genre;}
ListRecords.cpp:
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cassert>
#include <fstream>
#include <algorithm>
#include "header.h"
using namespace std;
#define TABLE_SIZE 200
ListRecords::ListRecords(char filename[]){
ifstream input(filename);
assert(("Error: File does not exist.", input != NULL));
string line;
line_num=0;
while (getline(input,line)){
line_num++;
}
//go back to beginning of file
input.clear();
input.seekg(0, ios::beg);
char lines[TABLE_SIZE][TABLE_SIZE];
int i=0;
// load lines of file into array
while (i < line_num) {
input.getline(lines[i],TABLE_SIZE);
i++;
}
input.close();
books = new BookRecord*[TABLE_SIZE];
books2 = new InfoBookRecord*[TABLE_SIZE];
books3 = new TypeBookRecord*[TABLE_SIZE];
k=0;
for(i=0;i<line_num;i+=5){
// check for duplicate entries
int test=0;
for(int j=0;j<i/5;j++){
if(books[j]->getISBN() == atoi(lines[i+3])){
cout << "Found a duplicate ISBN... ignoring entry " << lines[i+3] << endl;
test=1;
}
}
// if not a duplicate entry, add to array
if(test==0){
int the_price;
cout << "Please enter price of " << lines[i] << ": " << endl;
cin >> the_price;
getline(cin,garbage);
string the_authorBio;
cout << "Please enter author bio of " << lines[i] << ": ";
cin >> the_authorBio;
getline(cin,garbage);
string the_genre;
cout << "Please enter the book genre of " << lines[i] << ": ";
cin >> the_genre;
getline(cin,garbage);
*(books2+k) = new InfoBookRecord(lines[i],lines[i+1],lines[i+2],atoi(lines[i+3]),the_price,the_authorBio);
*(books3+k) = new TypeBookRecord(lines[i],lines[i+1],lines[i+2],atoi(lines[i+3]),the_genre);
*(books+k) = new BookRecord(lines[i],lines[i+1],lines[i+2],atoi(lines[i+3]));
k++;
}
else
i+=5;
}
}
void ListRecords::insertBookInfo(BookRecord record){
line_num+=5;
*(books+k) = new BookRecord(record.getTitle(),record.getAuthor(),record.getPublisher(),record.getISBN());
k++;
}
void ListRecords::printBookInfo(int bookISBN){
int found=0;
for(int i=0;i<k;i++){
if(books[i]->getISBN() == bookISBN){
if(to_string(books[i]->getISBN()).length()==9)
cout << endl << books[i]->getTitle() << endl << books[i]->getAuthor() << endl << books[i]->getPublisher() << endl << "0" << books[i]->getISBN() << endl;
if(to_string(books[i]->getISBN()).length()==10)
cout << endl << books[i]->getTitle() << endl << books[i]->getAuthor() << endl << books[i]->getPublisher() << endl << books[i]->getISBN() << endl;
found=1;
break;
}
}
if(found==0)
cout << "The record you requested was not found in the list." << endl;
}
bool compare_by_isbn(BookRecord* x,BookRecord* y) { return (x->getISBN() < y->getISBN()); }
bool compare_by_title(BookRecord* x,BookRecord* y) { return (x->getTitle() < y-> getTitle()); }
void ListRecords::printListByISBN(){
sort(books, books + k, compare_by_isbn);
printf(" %-22s %-22s %-17s %s\n", "Title", "Author", "Publisher", "ISBN");
cout << string(22, '-') << " " << string(22, '-') << " " << string(22, '-') << " " << string(10, '-') << endl;
for(int i=0;i<k;i++){
if(to_string(books[i]->getISBN()).length()==9)
printf("%-22.22s %-22.22s %-22.22s 0%d\n", books[i]->getTitle().c_str(), books[i]->getAuthor().c_str(), books[i]->getPublisher().c_str(), books[i]->getISBN());
if(to_string(books[i]->getISBN()).length()==10)
printf("%-22.22s %-22.22s %-22.22s %d\n", books[i]->getTitle().c_str(), books[i]->getAuthor().c_str(), books[i]->getPublisher().c_str(), books[i]->getISBN());
}
}
void ListRecords::printListByTitle(){
sort(books, books + k, compare_by_title);
printf(" %-22s %-22s %-17s %s\n", "Title", "Author", "Publisher", "ISBN");
cout << string(22, '-') << " " << string(22, '-') << " " << string(22, '-') << " " << string(10, '-') << endl;
for(int i=0;i<k;i++){
if(to_string(books[i]->getISBN()).length()==9)
printf("%-22.22s %-22.22s %-22.22s 0%d\n", books[i]->getTitle().c_str(), books[i]->getAuthor().c_str(), books[i]->getPublisher().c_str(), books[i]->getISBN());
if(to_string(books[i]->getISBN()).length()==10)
printf("%-22.22s %-22.22s %-22.22s %d\n", books[i]->getTitle().c_str(), books[i]->getAuthor().c_str(), books[i]->getPublisher().c_str(), books[i]->getISBN());
}
}
main.cpp:
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cassert>
#include <fstream>
#include <algorithm>
#include "header.h"
using namespace std;
#define TABLE_SIZE 200
int main(int argc, char* argv[]){
char filename[50];
cout << "Enter the name of a file to load:" << endl;
cin >> filename;
ListRecords listrecords(filename);
while(true){ // looping for the selection menu
int selection, n;
cout << "Please select a menu option:\n1) Insert a book record into the list\n2) Print information of a book with a given ISBN number\n3) Print the list of books sorted by ISBN\n4) Print the list of books sorted alphabetically by title\n5) Print the books also with info on price, author biography, and genre.\n6) Quit the program" << endl;
cin >> selection;
if(cin.fail()){ // make sure input is a digit
cout << "Invalid selection. Quitting program..." << endl;
break;
}
if(selection==1){
string in_title;
string in_author;
string in_publisher;
int in_isbn;
string junk;
getline(cin, junk);
cout << endl << "Please enter a title: ";
getline(cin, in_title);
cout << "Please enter an author: ";
getline(cin, in_author);
cout << "Please enter a publisher: ";
getline(cin, in_publisher);
cout << "Please enter an ISBN: ";
cin >> in_isbn;
BookRecord new_record(in_title, in_author, in_publisher, in_isbn);
listrecords.insertBookInfo(new_record);
cout << endl << "The record has been added to the list." << endl;
cout << endl << endl;
}
if(selection==2){
int in_isbn;
cout << endl << "Please enter ISBN number: " << endl;
cin >> in_isbn;
listrecords.printBookInfo(in_isbn);
cout << endl << endl;
}
if(selection==3){
cout << endl;
listrecords.printListByISBN();
cout << endl << endl;
}
if(selection==4){
cout << endl;
listrecords.printListByTitle();
cout << endl << endl;
}
if(selection==5){
int in_isbn;
cout << endl << "Please enter ISBN number: " << endl;
cin >> in_isbn;
cout << endl << "List of books also with info on price and author biography: " << endl;
cout << endl << endl;
// problem here
// extraListRecords extras;
//ListRecords *bookextras= &extras;
// bookextras->printBookInfo(in_isbn);
cout << endl << "List of books also with info on genre: " << endl;
}
if(selection==6){
cout << endl << "Program terminating normally..." << endl;
break;
}
} // end of while(true) loop
return 0;
};
Makefile:
LFLAGS = -Wno-write-strings -std=c++11
CFLAGS = -Wno-write-strings -std=c++11 -c
myprogam: main.o BookRecord.o ListRecords.o
g++ $(LFLAGS) -o myprogram main.o BookRecord.o ListRecords.o header.h
main.o: main.cpp header.h
g++ $(CFLAGS) main.cpp
BookRecord.o: BookRecord.cpp header.h
g++ $(CFLAGS) BookRecord.cpp
ListRecords.o: ListRecords.cpp header.h
g++ $(CFLAGS) ListRecords.cpp
clean:
rm *.o
rm myprogram
I commented out the two parts giving me trouble. One is at the end of header.h, and the other is near the end of main.cpp.
When I try to make this, I get the error
main.cpp:(.text+0x4c7): undefined reference to `extraListRecords::extraListRecords()'
collect2: error: ld returned 1 exit status
make: *** [myprogam] Error 1
I've tried a few other attempts at that subclass with the virtual function, such as adding the initialization of book2 and book3 to the body of its constructor, so writing its constructor as extraListRecords(char filename[]) :ListRecords(filename){ / the chunk of code in ListRecords.cpp above around line 55 / }
Thanks a bunch for the help!
Aucun commentaire:
Enregistrer un commentaire