Hello Leonardo797,
I have been looking at your last code all morning and I am not sure where to start.
You have gone from a good start with your original code to something that makes no sense.
To start with, on the left, and changed to, on the right:
1 2 3 4 5 6 7
|
struct Item
{
char description[20];
double price;
int in_stock; //--->
int sold; //--->
};
|
struct Item
{
char description[DESC_SIZE];
double price;
int quantitySold;
int quantityInStock;
}; |
Although I do like the variable names in the new struct the order they are defined in needs to be the same as the old struct. Or you will have to create a whole new file to match the new struct.
Next is your global variable. You are counting on the variable being defined as a global variable to be initialized when it is defined. DO NOT count on this. There is no guarantee this will happen. This may be true for the newer compilers, but not for older compilers.
Since it is used often:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
void displayInventory()
{
Item record; // To hold an inventory record
// Open the file for binary input.
fstream inventory("inventory.dat", ios::in | ios::binary);
// Now read and display the records.
inventory.read(reinterpret_cast<char *>(&record), sizeof(record));
int width = 14;
cout << setw(5) << "ITEM#" << setw(2 * width) << "DESCRIPTION" << setw(width) << "PRICE" << setw(width) << "#INSTOCK" << setw(width) << "#SOLD" << endl;
for (int i = 0; i < NO_OF_CURRENT; i++)
cout << setw(5) << i + 1 << setw(2 * width) << items[i].description << setw(width) << items[i].price << setw(width) << items[i].quantityInStock << setw(width) << items[i].quantitySold << endl;
}
|
This does not work.
Line 3 creates an object of type "Item" that is local to the function.
Line 6 creates an object of "fstream" to read the file and opens the file. This is OK.
Line 9 reads the first record in the file.
Line 11 is OK, but makes me think that you are not understanding the use of "setw()".
Line 15 is fine, but could be updated later on.
Line 16 is wrong. First in the use of the "setw()"s but mostly in what you are using to print.
You have read the file for the first record, but you are trying to print the array that is empty and never been changed. At this point it does not matter if the main menu choice is 2, 3 or 4 there is nothing in the array to print.
Make a choice either to print the file or the array.
It has been pointed out several times that the program never reads the file to fill the array with its information. This needs to be done.
The function:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
void createEmptyInventory()
{
char ch;
cout << "Warning! This will destroy all data." << endl;
cout << "Press 'y' to continue: ";
cin >> ch;
if (ch != 'y')
return;
cout << "\nInventory Is Now Empty" << endl;
// Create an empty Inventory item structure.
Item record = { "", 0.0, 0, 0 };
// Open the file for binary output.
fstream inventory("inventory.dat", ios::out | ios::binary);
// Write the blank records.
// Close the file.
//inventory.write(reinterpret_cast<char *>(&record),
// sizeof(record));
//inventory.close();
}
|
Line 9 only accepts a lower case "y" to make the condition false, but rejects an upper case "Y". Somehow you need to account for both cases.
Line 12 is OK,but really done to early and in the end it does not apply based on the rest of the code.
Line 15 creates an object of type "Item". This becomes a local variabel to the function which you set when you define it.
Line 18 creates a file stream and opens the file, but you should check that the file is open before you try to use it. Even though it is an output file that will be created if it does not exist there are still other reasons that this may not happen, so it needs to be checked. This should be done every time you open a file stream for input or output.
After this you do not do anything to the array or write anything to the file to change anything.
Your original code was better.
For the function:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
|
void editInventory()
{
Item record;
long recNum;
// To hold an inventory record
// To hold a record number
fstream inventory("inventory.dat", ios::in | ios::out | ios::binary);
// Open the file in binary mode for input and output.
// Get the record number of the desired record.
displayInventory();
cout << "\Which record do you want to edit? ";
cin >> recNum;
recNum--;
// Move to the record and read it.
inventory.seekg(recNum * sizeof(record), ios::beg);
inventory.read(reinterpret_cast<char *>(&record), sizeof(record));
//Display the record contents.
cout << "\nDescription: ";
cout << record.description << endl;
cout << "Price: ";
cout << record.price << endl;
cout << "In Stock: ";
cout << record.quantityInStock << endl;
cout << "Sold: ";
cout << record.quantitySold << endl;
// Get the new record data.
cout << "\nEnter the new data:\n";
cout << "Description: ";
cin.ignore();
cin.getline(record.description, DESC_SIZE);
cout << "Price: ";
cin >> record.price;
cout << "In Stock: ";
cin >> record.quantityInStock;
cout << "Quantity Sold: ";
cin >> record.quantitySold;
// Move back to the beginning of the this record's position.
inventory.seekp(recNum * sizeof(record), ios::beg);
// Write the new record over the current record.
//ventory.write(reinterpret_cast<char *>(&record), sizeof(record));
saveInventory();
// Close the file.
inventory.close();
}
|
Line 3 and 4 are OK.
Line 12 displays the inventory, but there is nothing to display at this point.
What is displayed is:
ITEM# DESCRIPTION PRICE #INSTOCK #SOLD
1 0 0 0
2 0 0 0
3 0 0 0
4 0 0 0
5 0 0 0
6 0 0 0
7 0 0 0
Which record do you want to edit?
|
So when you enter a number 1 - 7 at line 15 you are off by 1.
Line 20 will reposition the file pointer, but if you had chosen 1 it will actually display record 2 not 1, which starts at (0) zero.
You need line 17, so that the "seekg" will position the file pointer in the right place.
I have already showed you how you can take the 8 lines 24 - 31 and shorten them to just 4 lines, but if you are not interested or ready for this that is fine.
Then again this is taking information from a file when it should be using the array.
Then after you have take all the input and changed the local variable you do not use it to change the array, but you do call "saveInventory();" to save an array that has not changed. Not what you want.
Your original code is better. The menu and switch is good it just to be in a loop to edit 1 or more variables instead of doing 1 at a time or entering information that may not change.
Over all your original code is better to work with than this new one.
And do not discount what
seeplus has posted. Even if you can not use his code directly what is there is worth considering.
Sorry I have not started on the "makeAnOrder" function yet.
Andy