Last active
December 15, 2015 14:58
-
-
Save ereidland/5278241 to your computer and use it in GitHub Desktop.
Example 5 at Library
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define MAX_INVENTORY 100 | |
//Arguments to use in cin.ignore: | |
#define IGNORE_ARGS 256, '\n' | |
#include <fstream> | |
#include <iomanip> | |
#include <iostream> | |
#include <string> | |
using namespace std; | |
bool readInventory(string filename); | |
double checkout(); | |
bool updateInventory(string filename); | |
struct Product | |
{ | |
int code; //Product code. | |
string name; //Product name. | |
double cost; //Product cost. | |
bool byPounds; //By pounds (or by unit) | |
//Union: Variables of the same type take up the same place in memory, | |
//And since we don't access either of them at the same time, the code doesn't break. | |
union | |
{ | |
double pounds; //Pounds in inventory. | |
int units; //Units in inventory. | |
}; | |
//Normal if: | |
//if (condition) | |
// { code } | |
//else { other code } | |
//The inline if: | |
//(condition ? code : other code) | |
void print() //Print out this product. | |
{ | |
cout << setw(8) << "Name:" << name << endl | |
<< setw(8) << "Code:" << code << endl | |
<< setw(8) << "Cost:" << cost << endl | |
<< setw(8) << "By pounds:" << (byPounds ? "true" : "false") << endl | |
<< setw(8) << (!byPounds ? "Units:" : "Pounds:") << (byPounds ? pounds : units) << endl; | |
} | |
}; | |
Product * inventory; //Pointer to first element in array of products. | |
int inventoryCount = 0; | |
Product * getProduct(int code); | |
int main() | |
{ | |
//1. Read in and store inventory. | |
readInventory("items.txt"); //Read in the inventory from items.txt; | |
double cost = checkout(); | |
cout << "Total cost: $" << setprecision(2) << fixed << cost << endl; | |
//2. Get item code from user. | |
//3. If valid | |
//4. Request units/pounds based on product type. | |
//5. If valid and quantity is in inventory | |
//6. Add to cart, go to step 2. | |
//7. else if 0, exit | |
//8. else print error, go back to 2. | |
//9. Print receipt. If over 50, discount 5% | |
updateInventory("items.txt"); | |
//Delete the inventory. Note the [] required to let delete know we are deleting an array and not a pointer. | |
delete [] inventory; | |
return 0; | |
} | |
bool readInventory(string filename) | |
{ | |
//Initialize product array of MAX_INVENTORY size. | |
inventory = new Product[MAX_INVENTORY]; | |
inventoryCount = 0; | |
ifstream in(filename); | |
if (!in.is_open()) | |
{ | |
cout << "Could not open " << filename << endl; | |
return false; | |
} | |
while (!in.eof() && inventoryCount < MAX_INVENTORY) | |
{ | |
Product product; | |
in >> product.code; | |
if (in.fail()) | |
{ | |
cout << "Invalid product code." << endl; | |
return false; | |
} | |
in >> product.name; | |
if (in.fail()) | |
{ | |
cout << "Invalid product name." << endl; | |
return false; | |
} | |
in >> product.byPounds; | |
if (in.fail()) | |
{ | |
cout << "Invalid product byPounds (bool)." << endl; | |
return false; | |
} | |
in >> product.cost; | |
if (in.fail()) | |
{ | |
cout << "Invalid product cost." << endl; | |
return false; | |
} | |
if (product.byPounds) | |
{ | |
in >> product.pounds; | |
if (in.fail()) | |
{ | |
cout << "Invalid product weight." << endl; | |
return false; | |
} | |
} | |
else | |
{ | |
in >> product.units; | |
if (in.fail()) | |
{ | |
cout << "Invalid product count." << endl; | |
return false; | |
} | |
} | |
product.print(); | |
inventory[inventoryCount] = product; | |
inventoryCount++; | |
} | |
return true; | |
} | |
Product * getProduct(int code) | |
{ | |
for (int i = 0; i < inventoryCount; i++) | |
if (inventory[i].code == code) //If codes match. | |
return &inventory[i]; //Returning refrence to inventory[i] | |
return NULL; | |
} | |
double checkout() | |
{ | |
double cost = 0; | |
int code; | |
while (true) | |
{ | |
cout << "Enter product code: " << endl; | |
cin >> code; | |
if (cin.fail()) | |
{ | |
cout << "Invalid product code!" << endl; | |
cin.clear(); | |
cin.ignore(IGNORE_ARGS); | |
continue; //Continue skips all execution in this iteration of the loop, allowing us to jump to the next iteration. | |
} | |
if (code == 0) | |
{ | |
cout << "Done checking out. Cost: " << cost << endl; | |
if (cost > 50) | |
{ | |
cout << "Discount: " << setprecision(2) << fixed << cost * 0.05 << endl; | |
cost *= 0.95; //Discount by %5. | |
} | |
return cost; | |
} | |
Product * item = getProduct(code); | |
if (!item) | |
{ | |
cout << "Item not found."; | |
continue; | |
} | |
if ((item->byPounds && item->pounds <= 0) || (!item->byPounds && item->units <= 0)) | |
{ | |
cout << "There's nothing left of that item."; | |
continue; | |
} | |
cout << "Enter " << (item->byPounds ? "pounds" : "weight") << " (max " << (item->byPounds ? item->pounds : item->units) << "): "; | |
if (item->byPounds) | |
{ | |
double pounds; | |
cin >> pounds; | |
if (cin.fail()) | |
{ | |
cout << "Invalid weight." << endl; | |
} | |
else if (pounds > item->pounds) | |
{ | |
cout << "Not enough pounds left of that item." << endl; | |
} | |
else if (pounds < 0) | |
{ | |
cout << "Can't buy a negative weight (that's called giving)" << endl; | |
} | |
else | |
{ | |
double added = pounds * item->cost; | |
item->pounds -= pounds; | |
cout << "Added " << pounds << " pounds of " << item->name << " for $" << setprecision(2) << fixed << added << endl; | |
cost += added; | |
} | |
} | |
else | |
{ | |
int units; | |
cin >> units; | |
if (cin.fail()) | |
{ | |
cout << "Invalid weight." << endl; | |
} | |
else if (units > item->units) | |
{ | |
cout << "Not enough units left of that item." << endl; | |
} | |
else if (units < 0) | |
{ | |
cout << "Can't buy a negative units (that's called giving)" << endl; | |
} | |
else | |
{ | |
double added = units * item->cost; | |
item->units -= units; | |
cout << "Added " << units << " of " << item->name << " for $" << setprecision(2) << fixed << added << endl; | |
cost += added; | |
} | |
} | |
//Make sure it's clean for the next iteration. | |
cin.clear(); | |
cin.ignore(IGNORE_ARGS); //So input doesn't keep coming back on fail. | |
} | |
return cost; | |
} | |
bool updateInventory(string filename) | |
{ | |
ofstream out(filename); | |
for (int i = 0; i < inventoryCount; i++) | |
{ | |
//Write out all elements separated by space. | |
out << inventory[i].code << " " | |
<< inventory[i].name << " " | |
<< inventory[i].byPounds << " " | |
<< inventory[i].cost << " " | |
<< (inventory[i].byPounds ? inventory[i].pounds : inventory[i].units) << endl; | |
} | |
out.close(); | |
return false; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Removed #define/#ifdef and #include, as they were only used in example.