I'm writing a program to store book data, the program is done for the most part, however it crashes at seemingly random places when I'm inputting data into the arrays.
Yes, this is for an assignment, however this is a problem not even my instructor could identify and help me fix. The code from the program is completely finished except for this error.
I'm using 3-dim arrays to store this data. I'm really not sure where the problem is in the code. Here's an example of inputting some test data, the last line here is a complete crash (without a popup however). The program just quits working without notice after I entered the third ISBN at the bottom of the screenshot. The place is quits working at varies with different test data.
Ouch. Way too many *s all over the place. That's almost painful to look at.....
I was thinking about this more. OP, why do you need three dimensional arrays? A single array of structs seems like it would suffice and would be a whole lot easier to maintain. No serious programmer would write code like that. I hope that's not what you're being taught.
Unless I misunderstood your point and it needs to match what was declared in the 3dim array it's entering into (in this case, 50). I tried it both ways and it still crashes at the same spot (with the same test data).
Unless I misunderstood your point and it needs to match what was declared in the 3dim array it's entering into (in this case, 50). I tried it both ways and it still crashes at the same spot (with the same test data).
@GCDEF, Lindley:
My professor requires it this way. In order to teach us pointers, we make every array a pointer. This assignment also specifies we use 3-dim arrays.
Unless I misunderstood your point and it needs to match what was declared in the 3dim array it's entering into (in this case, 50). I tried it both ways and it still crashes at the same spot (with the same test data).
You missed the point. How many characters are you allocating for tempauthor?
And seriously, if I were your instructor I'd have you rewrite it without 3d arrays. That's just not how to tackle this problem.
@GCDEF, Lindley:
My professor requires it this way. In order to teach us pointers, we make every array a pointer. This assignment also specifies we use 3-dim arrays.
I say this very sincerely. Drop the class and look for a teacher with a clue. First, this is seriously an abhorrent way to code. If somebody that worked for me wrote that, they'd have to rewrite it or look for another job. If you took it to a job interview, it would be a very short interview. Also, the error in your code is very easy to spot. The fact that your instructor missed it doesn't bode well either. I mean it. You're being seriously led astray. What school is this? Can you paste the text of the actual assignment in here?
On the bright side, kudos for your first post having code tags and a good, easy to read indentation style.
Last edited by GCDEF; April 21st, 2010 at 07:42 PM.
I see what you mean now about allocating. I'll get to it and post back with any other questions.
Here is the entire assignment:
Code:
CPSC 121 Assignment 4
Books
Introduction
This course is all about arrays. Here is another problem to solve that uses arrays. We'll continue practicing the use of arrays through the end of the semester. This program has one new kind of array -- a three dimensional array.
Problem description
Suppose you work for Barnes and Noble. A manager asks you to make software to track the inventory of books. Make a C++ program that will do the job of managing the data about these books.
The data relevant to a single book are these: isbn, author, publisher, title, edition number, year, number of pages, manufacturer's retail price, b&n discounted price, and number of copies in stock.
Create arrays to hold the data. You may assume that the total number of books will never exceed 25 for this simple homework.
Activities requested by the management
Display all the books in a orderly readable form.
Add a single book to the inventory.
Find the oldest book in the inventory
Find the cheapest book according to discounted prices
Display only books published in a given year
Sort books by author: then books will display in order by author name
Find the books with number of pages exceeding a certain minimum.
//Find all the information about a book given its title = not used in this assignment.
Arrays
It is important to make the right foundation before programming. After too much program has been written with the wrong foundation it is too hard to go back and start a new design. First collect together data of the same type into arrays. That means integer data will be in an integer array, float data in a float array, and so on. Be sure to come to an understanding of the problem to the point that you know the purpose of every piece of data.
Functions
Here is a list of functions to be included in your program. Your program must have these functions, but you may create more functions if that helps.
1. A function that reads all the data regarding one book and places those data into their respective arrays. The prototype probably looks like this.
void readonebook(char *** info, int ** data, float ** costs, int numberbooksininventory);
2. A group of function that will be called by #1 above. Here are the prototypes.
char * readauthor();
char * readtitle();
char * readpublisher();
float readmsrp();
float readbandn();
int readisbn();
and others of your choice.
3. A function that will show all books in the inventory. The prototype looks like this.
void showallbooks(char *** info, int ** data, float ** prices, int numberbooksatbarnesandnoble);
4. A function that will output only one book. The prototype looks like this.
void displayonebook(char * title, char * publisher, char * author, int isbn, int edition, int year, int pages, int copies, float msrp, float discountprice);
5. A function that will find the index number of the oldest book in the inventory.
int findoldest(int ** bookdata, int numberofbooksintheinventoryatbarnesandnoble);
6. A function that will find the index number of the cheapest book sold by Barnes and Noble according to discount prices.
int findcheapestbookintheinventory(float ** bookprices, int totalbooksatbandn);
7. A function that will show all the books published in a certain year. These prototypes are lots of fun.
void showoneyearofbooks(char *** information, int ** numbericdata, float ** dollars, int totalcountofallbooks, int specialyear);
8. A function that will show all the big books; that means, all books with more that a certain minimum number of pages. This is more fun than any programmer should have:
void showallbigbooks(char *** textinformation, int ** numberbookinformation, int ** costs, int grandtotalnumberinventory, int minimumpagecount);
9. A function that will create the 3-dim array. This function does not have to store any useful information in the array – it simply has to reserve space for the array. Main will call this function to establish the existence of the array.
char *** createtextarray();
In CPSC131 functions that create objects (like array) are especially important. Such function are designated as “constructor functions”.
10. A function that will create the array of prices. Main will call this function. This is one of those constructor functions. float ** createprices();
Test data
Display all the data in organized format. //Here at the beginning there are no data.
Add this book to the inventory
0132084945
Daniel Liang
Introduction to Java
Prentice-Hall
7
2009
1297
89.00
78.00
30
Add this book to the inventory
1590599918
Keir Thomas
Beginning Ubuntu Linux
Apress
3
2008
729
59.99
50.00
10
Add this book to the inventory
1861004060
Paul Wilton
Beginning Javascript
Wrok
1
2000
1018
62.50
55.00
7
Find oldest book in the inventory
Add this book to the inventory
0127386718
Peter Wayner
Disappearing Cryptography
Academic Press
1
1996
295
33.95
25.50
4
Add this book to the inventory
0764539108
Danny Briere
Wireless Home Networking for Dummies
Wiley Publishing
1
2003
362
25.75
20.25
11
Add this book to the inventory
0767908155
Mario Livio
The Golden Ratio
Broadway Books
1
2002
294
23.95
21.60
23
Add this book to the inventory
0691118221
Paul J. Nahin
Dr. Euler's Fabulous Formula
Princeton University Press
1
2006
380
24.99
19.00
17
Display all the books' data in organized format
Find the cheapest book in B&N inventory; display its information
Find all books with more than 400 pages; display all their information.
Sort the books according to author's (first) name
Display all the books in the inventory
Add this book
0691099839
Julian Havil
Gamma: Exploring Euler's Constant
Princeton University Press
1
2003
266
24.99
20.00
17
Find all books with more than 270 pages; display all their information.
Show the information about all books published in 2003
Find oldest book in the inventory
Show the information about all books published in 2001
Add this book
0375424045
Leonard Mlodinow
The Drunkard's Walk
Pantheon Books
1
2008
252
27.45
22.10
29
Add this book
0136053068
Paul Deitel
Java How to Program
Prentice Hall
8
2009
1506
85.99
65.00
40
0470497025
Jeff Duntemann
Assembly Language Step by Step
Wiley and Sons
3
2009
648
65.00
40.95
12
0122407601
Richard Epstein
The Theory of Gambling and Statistical Logic
Academic Press
2
1977
464
45.00
24.95
4
Show the information about all books published in 2008
Sort the inventory by author's name
Find all books with more than 450 pages; display all their information.
Find and show the cheapest book in the inventory
Find and show the oldest book in the inventory
Display all the books in the inventory
Quit the program
That's a reasonable assignment except for the three dimensional part. A single dimensional array is all you need. I'm having trouble imagining what he's even thinking.
It is important to make the right foundation before programming. After too much program has been written with the wrong foundation it is too hard to go back and start a new design. First collect together data of the same type into arrays. That means integer data will be in an integer array, float data in a float array, and so on. Be sure to come to an understanding of the problem to the point that you know the purpose of every piece of data.
Funny how it starts out by saying exactly the right thing, and then goes on to say exactly the wrong thing. Parallel arrays are to be avoided in favor of more cohesive data structures. Data should be grouped by relevance, not just by data type.
The one benefit I can see to making you do it this way is that if you can keep track of all that indirection, you'll have pointers down pat. Plus it'll make you appreciate the right approach all the more when you see it.
Thank you very much for your help! Everything seems to be working fine now.
I ended up just passing the array to the functions and entering directly into the array, skipping the middleman for the char functions. I left the float/int ones alone since they worked properly. Did I go about this the right way? I can't rely on my teacher to comment on this, it would seem.
Thank you very much for your help! Everything seems to be working fine now.
I ended up just passing the array to the functions and entering directly into the array, skipping the middleman for the char functions. I left the float/int ones alone since they worked properly. Did I go about this the right way? I can't rely on my teacher to comment on this, it would seem.
I'm glad it works, but from a design standpoint, no it's not right.
Ideally, assuming you aren't using a database, you'd want a class or struct that held information about the books, and store those structs in an array or list. I haven't tried to figure out how you're using 3D arrays, but you'd really have to go out of your way to come up with a really convoluted design to make them fit.
Unfortunately, in school, if it's what your instructor wants, it's right. Keep in mind it's a learning exercise I guess. In the real world, code won't look like that.
I thought you might appreciate seeing how this sort of task should be implemented. Or at least a better approach---there are of course many ways it could be done. Files are attached, plus the code is shown here.
Given your assignment requirements you cannot simply use the attached, of course (which is why I did it----we don't do homework), but it does all the same things. The biggest difference from the assigned tasks is that it loads up all the books at once instead of doing some of the searches before they're all in. Given that decision, I omitted some of the outputs which would have been duplicates.
This took about 45 minutes to write. And guess how much debugging it took to get this working correctly? After I finished writing it, I found I had 4 compile errors. And once I fixed those, everything worked the first time I ran it. There is no way in hell anyone writing a program involving a dozen triple-pointers would be able to make such a claim.
If you think all of those very-similar comparator functors are a bit of a pain, you're right---that's why C++1x is introducing lambda functions, which are a sort of notation for writing this sort of functionality even more compactly.
Code:
/*
* inventory.cpp
*
*
* Created by Lindley French on 4/21/10.
* Copyright 2010 __MyCompanyName__. All rights reserved.
*
*/
#include <vector>
#include <string>
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <functional>
using namespace std;
struct Book
{
string name;
string author;
string publisher;
int ISBN;
int edition;
int year;
int pages;
double MSRP;
double BNprice;
int inStock;
};
struct YearComparator
{
bool operator()(const Book &b1, const Book &b2) const
{
return b1.year < b2.year;
}
};
struct AuthorComparator
{
bool operator()(const Book &b1, const Book &b2) const
{
return b1.author < b2.author;
}
};
struct DiscountedPriceComparator
{
bool operator()(const Book &b1, const Book &b2) const
{
return b1.BNprice < b2.BNprice;
}
};
struct BigBookCondition: unary_function<Book, bool>
{
int minsize;
BigBookCondition(int minsize_): minsize(minsize_)
{}
bool operator()(const Book &b) const
{
return b.pages >= minsize;
}
};
struct YearCondition: unary_function<Book, bool>
{
int targetyear;
YearCondition(int targetyear_): targetyear(targetyear_)
{}
bool operator()(const Book &b) const
{
return b.year == targetyear;
}
};
istream& operator>> (istream &in, Book &b)
{
in >> b.ISBN;
in.ignore(100,'\n');
getline(in, b.author);
getline(in, b.name);
getline(in, b.publisher);
in >> b.edition;
in >> b.year;
in >> b.pages;
in >> b.MSRP;
in >> b.BNprice;
in >> b.inStock;
return in;
}
// Output could be labelled and made more fancy-looking, but it's a good idea to make the input and output methods use the same format.
ostream& operator<< (ostream &out, const Book &b)
{
out << b.ISBN << "\n";
out << b.author << "\n";
out << b.name << "\n";
out << b.publisher << "\n";
out << b.edition << "\n";
out << b.year << "\n";
out << b.pages << "\n";
out << fixed << setprecision(2) << b.MSRP << "\n";
out << fixed << setprecision(2) << b.BNprice << "\n";
out << b.inStock;
return out;
}
void readInventory(vector<Book> &inventory, const string &filename)
{
ifstream in(filename.c_str());
Book tmp;
while (in >> tmp)
inventory.push_back(tmp);
}
void listInventory(const vector<Book> &inventory)
{
for (unsigned i = 0; i < inventory.size(); i++)
cout << inventory[i] << endl << endl;
}
int findOldest(const vector<Book> &inventory)
{
return distance(inventory.begin(),
min_element(inventory.begin(),inventory.end(),YearComparator()));
}
int findCheapestDiscounted(const vector<Book> &inventory)
{
return distance(inventory.begin(),
min_element(inventory.begin(),inventory.end(),DiscountedPriceComparator()));
}
int sortByAuthor(vector<Book> &inventory)
{
sort(inventory.begin(),inventory.end(),AuthorComparator());
}
int listBooksFromYear(const vector<Book> &inventory, int year)
{
vector<Book> yearbooks;
remove_copy_if(inventory.begin(),inventory.end(),back_inserter(yearbooks),not1(YearCondition(year)));
cout << "Books from " << year << ":\n";
listInventory(yearbooks);
}
int listBooksOverSize(const vector<Book> &inventory, int minpages)
{
vector<Book> bigbooks;
remove_copy_if(inventory.begin(),inventory.end(),back_inserter(bigbooks),not1(BigBookCondition(minpages)));
cout << "Books over " << minpages << " pages:\n";
listInventory(bigbooks);
}
int main(int argc, char **argv)
{
if (argc < 2)
printf("Usage: Inventory <bookfile>\n");
vector<Book> inventory;
readInventory(inventory, argv[1]);
cout << "Oldest book:\n" << inventory[findOldest(inventory)] << endl;
cout << "Cheapest book:\n" << inventory[findCheapestDiscounted(inventory)] << endl;
listBooksOverSize(inventory, 400);
sortByAuthor(inventory);
cout << "Complete inventory sorted by author:\n";
listInventory(inventory);
listBooksOverSize(inventory, 270);
listBooksFromYear(inventory, 2003);
listBooksFromYear(inventory, 2001);
listBooksFromYear(inventory, 2008);
listBooksOverSize(inventory, 450);
return 0;
}
EDIT: Okay, apparently I need to go switch off tabs in XCode....it was all much more aligned on my end.
Last edited by Lindley; April 21st, 2010 at 09:09 PM.
* The Best Reasons to Target Windows 8
Learn some of the best reasons why you should seriously consider bringing your Android mobile development expertise to bear on the Windows 8 platform.