fakeprogress@gmail.com wrote:[color=blue]
> For a homework assignment in my Data Structures/C++ class, I have to
> create the interface and implementation for a class called Book, create
> objects within the class, and process transactions that manipulate (and
> report on) members of the class.[/color]
This seems to be quite of an assignment for you, and seeing the code
you provided, you don't seem to be ready for it. However, I'll do my
best.
Note that your teacher seems to teach C more than C++. Specifically:
1) c-style strings are used instead of std::string
2) arrays are used instead of standard containers
3) problems with const-correctness
Since your class is in C++, I'll convert that program in C++.
[color=blue]
> Interface consists of:
> - 5 private variables
> char author[20];
> char title[25];
> char code[4];[/color]
These should be
std::string author;
std::string title;
std::string code;
[color=blue]
> int ncopies; // number of copies owned
> int onloan; // number of copies currently on loan
>
> - 5 public methods + 1 other method
> char *getAuthor; // returns (a pointer to) the author's name
> char *getTitle; // returns (a pointer to) the title
> char *getCode; // returns (a pointer to) the code of the book
> int getNcopies; // returns the number of copies owned by the
> library
> int getOnLoan; // returns the number of copies currently on
> loan[/color]
These should be
const std::string& getAuthor() const;
const std::string& getTitle() const;
const std::string& getCode() const;
int getNcopies() const;
int getOnLoad() const;
[color=blue]
> void Borrow( int ); // fixed number of copies are borrowed
>
> - 2 required constructors + 1 optional constructor
> Book( auth, tit, cd, ncop ) // creates an object of type Book
> with the info specified & assumes number of copies on loan is 0
> Book( auth, tit, cd, ncop, nonloan ) // creates an object of
> type Book with the info specified[/color]
These can be merged by giving nonload a default value (such as 0).
[color=blue]
> Book( ) // allows you to declare objects of type Book without
> initializing any values[/color]
And what does that give? Not all classes should have default
constructors. A book with no title or author or code is not a book.
Scrap that one.
[color=blue]
> * There is an initial file of information (called initbooks) that
> contains the information for the initial library. This information is
> stored on a file (and is not to be keyed in individually). Write a
> function readLibrary that will read the input file and create a book
> for each line of information read. As each data line is read, you
> should allocate a new record (possibly from within an available array)
> and initialize the data.
>
> Each data line contains an author, title, code, and number of copies.
> Some data lines contain information regarding the number of copies
> currently on loan. You should call the appropriate constructor and
> intialize the book to the type of data input.[/color]
There don't seem to be a format for that file. You'll have to devise a
simple one, such as a line separated list. Each book element is on a
line so you'll have five lines per book. That'll make it easier to read
strings containing spaces or commas (such as a book title).
[color=blue]
> * There is a file of transactions (called trans) containing
> transactions to be processed. Each transaction contains the following:
> transaction type: b (borrow) or r (return)
> account number: book code
> amount: number of copies to be borrowed/returned
> The appropriate object (book) corresponding to the book code should be
> located. The balance should be updated by the amount input. The update
> should be an increase (in the case of a deposit) or a decrease (in the
> case of a withdrawal).
>
> Write a function processTransactions that will read the file trans and
> process the transactions (and create a log).[/color]
So your file could contain
b 1234 2 // borrowed two copies of book 1234
That's easy to parse.
[color=blue]
> * Write a function printFull. This function will print the inventory of
> books held, including the author, title, code, number of copies in
> holding, and number of copies available. The sequence of this report
> should be in the sequence of the actual array at the time that it is
> printed.[/color]
That should be simple.
[color=blue]
> * Write a main function that will initialize the system and declare
> whatever variables are needed. You should create an array of objects of
> type Book (max size = 25). The main function should call the following
> functions:
> readLibrary
> printFull
> processTransactions
> printFull[/color]
Ok.
[color=blue]
> Now. I am NOT asking anyone to do this assignment for me.[/color]
I hope you're not :)
[color=blue]
> My class interface and the implementations of subsequent methods:
> --------------------------------------------------------[/color]
# include <string>
# include <vector>
[color=blue]
> class Book {
> private:
> char author[20];
> char title[25];
> char code[4];
> int ncopies;
> int onloan;[/color]
std::string author;
std::string title;
std::string code;
int ncopies;
int onload;
[color=blue]
> public:
> Book( char *auth, char *tit, char *cd, int ncop );
> Book( char *auth, char *tit, char *cd, int ncop, int
> nonloan );[/color]
Book(
const std::string& auth, const std::string& tit, const std::string&
cd,
int ncop, int nonload=0);
[color=blue]
> Book( );[/color]
Forget that one.
[color=blue]
> ~Book( );[/color]
You don't need a destructor.
[color=blue]
> char *getAuthor( );
> char *getTitle( );
> char *getCode( );
> int getNcopies( );
> int getOnLoan( );[/color]
Make these
const std::string& getAuthor() const;
const std::string& getTitle() const;
const std::string& getCode() const;
int getNcopies() const;
int getOnLoan() const;
[color=blue]
> void Borrow( int );
> void nReturn( int );[/color]
Take the habit of mentionning the parameters name, even if the compiler
doesn't use them.
void Borrow(int qty);
void nReturn(int qty);
[color=blue]
> };
>
> char *Book :: getAuthor( ) {
> return author;
> }[/color]
const std::string& Book::getAuthor() const
{
return author;
}
And do the same for the other member functions.
[color=blue]
> Now. Onto my question:[/color]
Good.
[color=blue]
> For some reason, I CANNOT figure out how to read in data. And how do I
> use the constructors? I'm really confused.
>
> If I declare:
> #define NBOOKS 40
> Book library[NBOOKS];[/color]
Don't! I won't start a discussion concerning arrays, they are evil. Use
a vector:
typedef std::vector<Book> Library;
int main()
{
Library lib;
readLibrary(lib);
[color=blue]
> then my readLibrary will look like this:
> --------------------------------------------------------
> int readLibrary( Book library ) {[/color]
Change that to
int readLibrary(Library& lib)
{
[color=blue]
> int i, j;
> char boundary[] = "STOP";
> j = 0; /* j counts number of records in library */
> for( i = 0; i < NBOOKS; i++ ) {
> fscanf( lib, "%s %s %s %d %d", &library[i].author,
> &library[i].title, &library[i].code, &library[i].ncopies,
> &library[i].onloan );
> if( strcmp( library[i].author, boundary ) != 0 )
> j++;
> else
> break;
> }
>
> return j;
> }[/color]
Now now now, how about some C++ here? As I said, putting book values on
different lines will make it easier.
// data example, books.dat
Bjarne Stroustrup
The C++ Programming Language, 3rd Edition
0001
10
2
# include <fstream>
# include <sstream>
int readLibrary(Library& lib)
{
// open the file
std::ifstream ifs("books.dat");
// we'll detect EOF inside
while (true)
{
// string values from the data file
// copies and load have a _s suffix (string)
// because they are temporary objects
// they will be converted to ints later on
std::string title, author, code, copies_s, loan_s;
// get five lines
getline(ifs, title);
getline(ifs, author);
getline(ifs, code);
getline(ifs, copies_s);
getline(ifs, loan_s);
// if we were at the end of file,
// or if there was any problems,
// one of the calls to getline() failed.
// we check it here
if (!ifs)
break;
// istringstream is useful for
// converting strings to integers
std::istringstream iss;
// convert copies_s to an int
int copies = 0;
iss.str(copies_s);
iss >> copies;
// convert loan_s to an int
int loan = 0;
iss.str(loan_s);
iss >> loan;
// create the book and add it
// to the library
lib.push_back(Book(title, author, code, copies, load));
}
}
As an example, here's how to output all the books in the library
void f(Library& lib)
{
for (Library::iterator itor=lib.begin(); itor!=lib.end(); ++itor)
{
Book& b = *itor;
std::cout
<< "Title: " << b.title() << "\n"
<< "Author: " << b.author() << "\n";
}
}
Jonathan