Thanks Trey / Charly / Jerry.
I have got the code running now.
Your right about the C thing. I'm currently wrestling with the fact that
my lecturer probably grew up with C and is pushing all his C habbits
into our C++ class. I am constantly trying to alter the way he teaches
to follow the C++ standard, but as I have only been learning programming
for about 3-4 months, its difficult to manage.
Anyway, I have a very strange bug in my program which I can't seem to
iron out. When I add more stock via the number1 in the menu, everything
is fine and I can build the stock up, however, if I then try and save
this to file (via menu num 4) is doesn't always save my new stock, it
stays as it was.
e.g. I currently have 11 items in stock. If I go to add another item, it
doesn't seem to save them.....I thought maybe it wasn't updating
'num_stock_items' but am unsure.
I've tried messing about with gdb and I seem to be getting strange
values for the integers I tried
int ans, ctr;
int num_stock_items = 0;
int num_bill_items = 0;
I've had no real experience with gdb, only from reading through the man
file, so I may be doing something wrong. Can anyone see why it may not
be saving correctly?
Here is my updated program (excuse the bad layout in the 'print bill'
function, I have not mastered text formatting yet) I'll continue when
I've got this bug sorted, as I have already done twice the work for this
assignment required. I'm just playing to further my knowledge now. (plus
the shot of a distinction...heh)
#include <iostream>
#include <fstream>
#include //for getch()
#include <iomanip>
using namespace std;
const int NUM_OF_ITEMS = 125;
struct StockItem
{
int code;
char desc[20];
float price;
}stock[NUM_OF_ITEMS];
struct BillLine
{
StockItem stock;
float weight;
float cost;
}bill_line[50];
/*
struct bill
{
bill_line items[20];
int num_lines;
};
*/
void cls(void) { system("cls"); } //function designed to aid
portability.
void disp_menu( void );
StockItem enter_data( void );
void delete_data( StockItem* );
void see_stock( StockItem*, int );
void writeToDisk( StockItem*, int );
int readFromDisk( StockItem* );
BillLine bill_item( void );
void print_bill ( BillLine*, int );
int main()
{
int ans, ctr;
int num_stock_items = 0;
int num_bill_items = 0;
do
{
do
{
disp_menu();
cin >> ans;
} while ((ans<1) || (ans>9));
switch (ans)
{
case 1:
stock[num_stock_items] = enter_data();
num_stock_items++;
break;
case 2:
delete_data( stock );
num_stock_items -= 1;
break;
case 3:
see_stock(stock, num_stock_items);
break;
case 4:
writeToDisk( stock, num_stock_items );
// NOT writing the whole array to disk.
break;
case 5:
num_stock_items = readFromDisk( stock );
// setting the number items we read from file
break;
case 6:
bill_line[num_bill_items] = bill_item();
num_bill_items++;
break;
case 7:
print_bill( bill_line, num_bill_items );
break;
default:
break;
}
}while (ans!=8);
return 0;
}
void disp_menu()
{
cout << "\n*** The Corner Shop ***\n\n";
cout << "Select an option: \n\n";
cout << "\t1. Enter new stock item " << endl;
cout << "\t2. Delete stock item " << endl;
cout << "\t3. See current stock " << endl;
cout << "\t4. Save stock to disk " << endl;
cout << "\t5. Load stock from disk " << endl;
cout << "\t6. Enter purchase order " << endl;
cout << "\t7. Print Bill " << endl;
cout << "\t8. Exit \n" << endl;
cout << "option> ";
}
StockItem enter_data(void)
{
StockItem stock_item;
cls();
cout << "\n\nWhat is the product code: ";
cin >> stock_item.code;
cout << "What is the product description: ";
cin.ignore();
cin.getline(stock_item.desc, 20);
cout << "What is the product price: ";
cin >> stock_item.price;
cls();
return (stock_item);
}
void delete_data(StockItem stock[NUM_OF_ITEMS] )
{
StockItem stock_temp[NUM_OF_ITEMS];
int item, n=0;
cls();
cout << "Enter item to delete ";
cin >> item;
item -= 1;
for(int i = 0; i < NUM_OF_ITEMS; i++)
{
if(i == item)
++n;
stock_temp[i] = stock[n];
++n;
}
for(int i = 0; i < NUM_OF_ITEMS; i++)
stock[i] = stock_temp[i];
cls();
}
void see_stock(StockItem stock[NUM_OF_ITEMS], int num_stock_items)
{
int ctr;
cls();
cout << "\n\nHere is the stock listing:\n\n";
for (ctr = 0; ctr < num_stock_items; ++ctr)
{
cout << "Item " << ctr+1 << endl;
cout << "Product Code: " << stock[ctr].code << endl;
cout << "Product Description: " << stock[ctr].desc << endl;
cout << "Price: " << stock[ctr].price << endl;
cout << "------------------------------------------------\n";
}
cout << "\nHit any key to continue.....\n";
getch();
cls();
}
void writeToDisk( StockItem* array, int numOfItems )
{
ofstream outfile( "items.txt" );
if (outfile.bad())
{
cout << "\n*** Error opening file ***\n";
}
for( int index = 0; index < numOfItems; index++ )
outfile.write( (char*)&array[index], sizeof(StockItem) );
cls();
}
int readFromDisk( StockItem* array )
{
int numOfItems = 0;
ifstream infile( "items.txt" );
if (infile.bad())
{
cout << "\n*** Error opening file ***\n";
}
StockItem tmp_stockItem;
// read from the file until we reach EOF
while( infile.read( (char*)&tmp_stockItem, sizeof(tmp_stockItem) ) )
{
// after a successfull read we store the the item into the array
memcpy( &array[numOfItems],
&tmp_stockItem,
sizeof( array[numOfItems] ) );
numOfItems++;
}
cls();
// returning the number of array items we read from the file
return numOfItems;
}
BillLine bill_item(void)
{
BillLine bill;
int item;
cls();
cout << "Enter item number purchased: ";
cin >> item;
item -= 1;
bill.stock = stock[item];
cout << "Weight: ";
cin >> bill.weight;
bill.cost = stock[item].price * bill.weight;
cls();
return (bill);
}
void print_bill ( BillLine bill_line[50], int num_bill_items )
{
cls();
cout << "THE CORNER SHOP\n\n";
cout << "Product " << setw(20) << "Kilos" << setw(20) << "Cost(£)"
<< endl;
for (int i=0; i
I think that Trey's comments are legitimate, but not the solution.
bill.stock is a single instance of a stock item.
I think you might be able to cast this:
bill.stock = *(&stock[item]);
What you apparently want to do is to copy a single instance.
Or you can use the memcpy function.
looking at the full code, i don't see why bill.stock is an array. the
only places it's used, it's always treated as a single instance.
setting
it to a pointer as you describe is probably the most memory efficient,
but
he would have to check in his delete_data function if the stock he's
deleting is referenced by bill. this seems to be a program for a
beginning level class and i'm not sure how far they've gotten. as such,
i
would suggest copying the data instead of pointing to it.
But, it appears that your code is really C being compiled with a C++
compiler.
that's pretty much the way most colleges are teaching it nowadays.
stuff
that could be taught in c (or even more simple langauges) all being
taught
in c++ or java. as it is, he is using c++ iostream for is user io.
note: i didn't give a specific solution out of old habit. when i was a
ta, i found that most students remembered solutions better if they found
it themselves. because of that i tended to only help them find the
problem and set them loose to find the solution. if they were still
having trouble, i'd give them a nudge or two in the right direction, but
would never simply give the solution to the problem at hand.
--
trey