line 123 as posted: int main() {
line 140 as posted: }
with this information and without the header, implementation files it's difficult to offer much diagnosis
One can avoid ugly (UGLY!!) non scalable and messy constructs like on line 97, by having a default case in the switch in a bool controlled while loop. The default case is like an else statement: use it to catch problems.
Without the header files "ItemToPurchase.h" and "ShoppingCart.h" it makes it difficult for anyone to compile your program.
Things I have noticed so far: you are missing "iosream" header file, The PrintMenu function has two problems. First each case has no "break" statement. Starting with case 'a' the "AddItem" function will be called followed by the "RemoveItem" function and so on until the closing brace of the switch which is the second problem. The closing brace of the switch is missing.
I offer this as a helpful tip. There is nothing wrong with coding blocks this way:
1 2 3 4 5
if (cin.fail()){
cin.ignore();
cin.clear();
return;
}
it is much easier this way:
1 2 3 4 5 6
if (cin.fail())
{
cin.ignore();
cin.clear();
return;
}
As you can see the opening and closing braces line up in the same column. This would make it easier to see that the switch has no closing brace. Just a thought, code in the way you feel best with.
Thank you the header files helped. After testing I think the only problem was the closing brace "}" on the switch. After commenting out the calls to member functions that I did not have the program compiled fine. When I commented out the closing brace of the switch there were errors two of which pointed to the main function among others.
Yes i figured that out but now i am having problems with some of my functions. If you re-read what i put in my question can you help me figure out what i did wrong?
You take in "nameOfCustomer" and "userDate", but never do anything with it. Line 135 should be written as" ShoppingCart cart{ nameOfCustomer, userDate }; because you have a constructor that takes two parameters.
Then on line 137 when you pass "cart" to the "PrintMenu" function it will have an instance of "cart" that contains the "customer name" and "date". In your function "PrintMenu" receive ShoppingCart& cart as a reference. Then you can pass it to other functions. This way when you call the "OutputCart" function it will have a correct "cart" instance of the class to work with.
In the "OutputCart" function you will need to change the cout statement to: cout << cart.GetCustomerName() << "'s Shopping Cart - " << cart.GetDate() << endl;. As you have it now the variables "nameOfCustomer" and "date" are empty or at the worst would contain garbage. These variables do not need to be parameters s "cart" should contain all the information you need.
The only part of the program I have not seen is the definition of the class member functions for each class, so it is hard to guess what they are doing.
I will work with the program some more and see what I can figure out.
string ShoppingCart::GetDate(){
return currentDate;
}
void ShoppingCart::AddItem(ItemToPurchase item){
vector < ItemToPurchase > cartItems;
cartItems.push_back(item);
return;
}
void ShoppingCart::RemoveItem(string itemName){
vector <ItemToPurchase> cartItems;
for (unsigned int i = 0; i < cartItems.size(); i++) {
if (cartItems.at(i).GetCustomerName() == itemName) {
cartItems.erase(cartItems.begin() + i);
return;
}
}
cout << "Item not found in cart. Nothing removed." << endl;
return;
}
void ShoppingCart::UpdateQuantity(string nameOfItem, int updatedQuantity){
for (unsigned int i = 0; i < cartItems.size(); i++) {
if(cartItems.at(i).GetCustomerName() == nameOfItem) {
cartItems.at(i).SetQuantity(updatedQuantity);
return;
}
}
cout << "Item not found in cart. Nothing modified." << endl;
return;
}
int ShoppingCart::GetNumItemsInCart(){
int numOfItems = 0;
for (unsigned int i = 0; i < cartItems.size(); i++) {
numOfItems = numOfItems + cartItems.at(i).GetQuantity();
}
return numOfItems;
}
int ShoppingCart::GetCostOfCart(){
int totalCost = 0;
for (unsigned int i = 0; i < cartItems.size(); i++) {
totalCost = totalCost + (cartItems.at(i).GetPrice() * cartItems.at(i).GetQuantity());
}
return totalCost;
}
void ShoppingCart::PrintTotal(){
cout << "Number of Items: " << GetNumItemsInCart() << endl;
for (unsigned int i = 0; i < cartItems.size(); i++) {
cout << endl << cartItems.at(i).GetCustomerName() << " " << cartItems.at(i).GetQuantity() << " @ $" << cartItems.at(i).GetPrice()
<< " = $" << (cartItems.at(i).GetQuantity() * cartItems.at(i).GetPrice());
}
if (cartItems.size() == 0) {
cout << "SHOPPING CART IS EMPTY" << endl;
}
cout << "Total: $" << GetCostOfCart() << endl << endl;
return;
}
void ShoppingCart::PrintDescriptions(){
cout << "Item Descriptions" << endl;
for (unsigned int i = 0; i < cartItems.size(); i++) {
cout << cartItems.at(i).GetCustomerName() << ": " << cartItems.at(i).GetDescription();
cout << endl;
}
return;
}
Thank you it makes a lot more sense now. I will get to work on it.
What I noticed right at first when I compiles the program is that both ShoppingCart.cpp
and ItemsToPurchase.cpp are missing the destructor function. a default destructor will work fine.
Just a minor point, any function that ends in return; the return is not needed because it is an automatic return from a function. It will not hurt if you leave them there.
In main if I did not mention this earlier, I think I did, you ask for a name and a date, but never do anything with them. Your "ShoppingCart" class has a constructor that takes two parameters. You need to use this: ShoppingCart cart{ nameOfCustomer, userDate };.
In void PrintMenu(ShoppingCart& cart), usually written this way, you define two strings for "nameOfCustomer" and "userDate". These are not needed because for "case Ii" "OutputItemsDescriptions" the function call only needs to have "cart" passed to the function and "nameOfCustomer" and "userDate" cn be obtained from "cart". In "OutputItemsDescriptions" in the "cout" staement it should be: cout << cart.GetCustomerName() << "'s Shopping Cart - " << cart.GetDate() << endl; and the same in the "OutputCart" function.
In the "AddItem" function I believe it works, but still have some testing to do. Although IMO asking the user for anything more than the quantity is a road to disaster.
Hope that helps,
Andy
Edit: In the "AddItem" function "newItemPrice" should be a double not an int. The same change should be made in the "ItemToPurchase" header file.
you define a vector and you push_back your information. This is fine except that "cartItems" is a local variable and is lost when the function ends, so no information is stored in the class. Remove line 3 and the function being a class member function will use "cartItems" that is defined in the class and all will be well.
When I started looking into the the header file for "ItemToPurchase" I noticed the the overloaded constructor is not written correctly. You receive several variables, but never use them to set the private member variables. It should look like this:
In the "AddItem" function in "main" you will need to move "ItemToPurchase addItem;" to be the next to last line of the function. This way when you construct the "addItem" object you can send all the variables you need to the overloaded constructor before yo call the "cart.AddItem(addItem);" function. All the lines after the "cin"'s will need to be deleted because the constructor will take care of these lines.
This should give you enough information to fix the problems I have mentioned and work on the other functions.
Yes Andy, this has helped tremendously. Thanks for also giving an explanation. We are getting to the point in the semester that once you start falling behind you get behind cause it just moves so fast the course. I really do want to learn and get better at this.