Working with Objects and classes

Im having trouble making my functions in the main work. The function isnt outputting correctly. It should look like this when option o is entered:

OUTPUT SHOPPING CART
John Doe's Shopping Cart - February 1, 2016
Number of Items: 8


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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#include <string>
#include <math.h>
#include "ItemToPurchase.h"
#include "ShoppingCart.h"

void OutputCart(ShoppingCart& cart, string& nameOfCustomer, string& date) {
    cout << "OUTPUT SHOPPING CART" << endl;
    cout << nameOfCustomer << "'s Shopping Cart - " << date << endl;
    cart.PrintTotal();
    
    return;
}
void OutputItemsDescriptions(ShoppingCart& cart, string& nameOfCustomer, string& date) {
    cout << "OUTPUT ITEMS' DESCRIPTIONS" << endl;
    cout << nameOfCustomer << "'s Shopping Cart - " << date << endl;
    cart.PrintDescriptions();
    
    return;
}

void AddItem(ShoppingCart &cart) {
    ItemToPurchase addItem;
    string newItemName;
    string newItemDescription;
    int newItemPrice;
    int newItemQuantity;
    
    cout << "ADD ITEM TO CART" << endl;
    cout << "Enter the item name: " << endl;
    cin.ignore();
    getline(cin, newItemName);
    addItem.SetName(newItemName);
    
    cout << "Enter the item description: " << endl;
    getline(cin, newItemDescription);
    addItem.SetDescription(newItemDescription);
    
    cout << "Enter the item price: " << endl;
    cin >> newItemPrice;
    addItem.SetPrice(newItemPrice);
    
    cout << "Enter the item quantity: " << endl;
    cin >> newItemQuantity;
    addItem.SetQuantity(newItemQuantity);
    
    cart.AddItem(addItem);
    
    return;
}
void RemoveItem(ShoppingCart &cart) {
    string removeItem;
    
    cout << "REMOVE ITEM FROM CART" << endl;
    cout << "Enter name of item to remove: " << endl;
    cin.ignore();
    getline(cin, removeItem);
    cart.RemoveItem(removeItem);
    
    return;
}
void UpdateQuantity(ShoppingCart &cart) {
    string updateQuantityItem;
    int updateQuantity;
    
    cout << "CHANGE ITEM QUANTITY" << endl;
    cout << "Enter the item name: " << endl;
    cin.ignore();
    cin >> updateQuantityItem;
    
    cout << "Enter the new quantity: " << endl;
    cin >> updateQuantity;
    cart.UpdateQuantity(updateQuantityItem, updateQuantity);
    
    return;
}
void PrintMenu(ShoppingCart cart) {
    char userChoice;
    string nameOfCustomer;
    string userDate;
    do {
        cout << "MENU" << endl;
        cout << "a - Add item to cart" << endl;
        cout << "d - Remove item from cart" << endl;
        cout << "c - Change item quantity" << endl;
        cout << "i - Output items' descriptions" << endl;
        cout << "o - Output shopping cart" << endl;
        cout << "q - Quit" << endl;
        cout << endl;
        do{
            cout << "Choose an option: " << endl;
            cin >> userChoice;
            if (cin.fail()){
                cin.ignore();
                cin.clear();
                return;
            }
        } while (userChoice != 'a' && userChoice != 'd' && userChoice != 'c' && userChoice != 'i' && userChoice != 'o' && userChoice != 'q');
        
        switch (userChoice){
            case 'q':
                return;
                
            case 'a':
                AddItem(cart);
                
            case 'd':
                RemoveItem(cart);
                
            case 'c':
                UpdateQuantity(cart);
                
            case 'i':
                OutputItemsDescriptions(cart, nameOfCustomer, userDate);
                
            case 'o':
                OutputCart(cart, nameOfCustomer, userDate);
                
        }}while (userChoice != 'q');
        return;
    }
    
    
    int main() {
        
        string customerName;
        string usersDate;
        
        cout << "Enter Customer's Name: " << endl;
        getline (cin, customerName);
        cout << "Enter Today's Date: " << endl;
        getline(cin, usersDate);
        cout << "Customer Name: " << customerName << endl;
        cout << "Today's Date: " << usersDate << endl;
        
        ShoppingCart cart;
        
        PrintMenu(cart);
        
        return 0;
        
    }
Last edited on
I get on erroron line 123 and 140

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
There is a missing closing brace on line 118.
The brace which is there matches the switch, not the do loop.
Last edited on
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.

Have a read of this:

http://www.cplusplus.com/forum/beginner/99203/#msg534078

There is no need for return statements in a void function, unless you want to exit the function early.

pass string by const reference where you can:

void OutputItemsDescriptions(const ShoppingCart& cart, const std::string& nameOfCustomer, const std::string& date) {

The return on line 95 is a problem - not what you want?


Hello rantiv,

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.

I will see what else I can find.

Hope that helps,

Andy
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
#ifndef ShoppingCart_h
#define ShoppingCart_h

#include <stdio.h>
#include <string>
#include <vector>
#include "ItemToPurchase.h"

using namespace std;

class ShoppingCart {
public:
    ShoppingCart();
    ShoppingCart(string nameOfCustomer, string date);
    string GetCustomerName();
    string GetDate();
    void AddItem(ItemToPurchase item);
    void RemoveItem(string itemName);
    void UpdateQuantity(string nameOfItem, int updatedQuantity);
    int GetNumItemsInCart();
    int GetCostOfCart();
    void PrintTotal();
    void PrintDescriptions();
    
    
private:
    string customerName;
    string currentDate;
    vector <ItemToPurchase> cartItems;
};

#endif /* ShoppingCart_h */
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
#ifndef ItemToPurchase_h
#define ItemToPurchase_h

#include <stdio.h>
#include <iostream>
#include <string>
#include <iomanip>

using namespace std;

class ItemToPurchase {
public:
    void SetName(string nameOfItem);
    string GetCustomerName();
    void SetPrice(int priceOfItem);
    int GetPrice();
    void SetQuantity(int quantityOfItem);
    int GetQuantity();
    void SetDescription(string descriptionOfItem);
    string GetDescription();
    void PrintItemCost();
    void PrintDescription();
    ItemToPurchase();
    ItemToPurchase(string nameOfItem, string descriptionOfItem, int priceOfItem, int quantityOfItem);
    
private:
    string itemName;
    string itemDescription;
    int itemPrice;
    int itemQuantity;
    
};

#endif /* ItemToPurchase_hpp */
Hello rantiv,

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.

Hope that helps,

Andy
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?
Hello rantiv,

Starting out in "main".

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.

Hope that helps,

Andy
Last edited on
#include "ItemToPurchase.h"

ItemToPurchase::ItemToPurchase() {
itemName = "none";
itemDescription= "none";
itemPrice = 0;
itemQuantity = 0;
return;
}

ItemToPurchase::ItemToPurchase(string nameOfItem, string descriptionOfItem, int priceOfItem, int quantityOfItem) {
itemName = "none";
itemDescription= "none";
itemPrice = 0;
itemQuantity = 0;
return;
}


void ItemToPurchase::SetName(string nameOfItem) {
itemName = nameOfItem;
return;
}

string ItemToPurchase::GetCustomerName() {
return itemName;
}

void ItemToPurchase::SetPrice(int priceOfItem) {
itemPrice = priceOfItem;
return;
}

int ItemToPurchase::GetPrice() {
return itemPrice;
}

void ItemToPurchase::SetQuantity(int quantityOfItem) {
itemQuantity = quantityOfItem;
return;
}

int ItemToPurchase::GetQuantity() {
return itemQuantity;
}

void ItemToPurchase::SetDescription(string descriptionOfItem) {
itemDescription = descriptionOfItem;
return;
}

string ItemToPurchase::GetDescription() {
return itemDescription;
}
void ItemToPurchase::PrintItemCost() {
cout << itemName << " " << itemQuantity << " @ $" << itemPrice;
cout << " = $" << itemQuantity * itemPrice;
}
void ItemToPurchase::PrintDescription() {
cout << itemName << " : " << itemDescription;
}


#include "ShoppingCart.h"
#include "ItemToPurchase.h"

ShoppingCart::ShoppingCart(){
string customerName = "none";
string currentDate = "January 1, 2016";
return;
}

ShoppingCart::ShoppingCart(string nameOfCustomer, string date){
string customerName = "none";
string currentDate = "January 1, 2016";
return;
}

string ShoppingCart::GetCustomerName(){
return customerName;
}

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;
}
Hello rantiv,

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.

Hope that helps,

Andy
Hello rantiv,

I am writing these comments as I find problems.

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.
Last edited on
Hello rantiv,

When the program gets to the point of calling:

1
2
3
4
5
void ShoppingCart::AddItem(ItemToPurchase item)
{
	vector < ItemToPurchase > cartItems;
	cartItems.push_back(item);
}


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:

1
2
3
4
5
6
7
ItemToPurchase::ItemToPurchase(string nameOfItem, string descriptionOfItem, int priceOfItem, int quantityOfItem)
{
	itemName = nameOfItem;
	itemDescription = descriptionOfItem;
	itemPrice = priceOfItem;
	itemQuantity = quantityOfItem;
}


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.

Hope that helps,

Andy
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.
Topic archived. No new replies allowed.