-3

I'm working through an old C++ textbook I found and I'm trying to understand classes. The file I am working on is called Grocery.cpp. I defined a class called GroceryItem and then defined a public function called dataEntry(). From within the dataEntry function, I'm calling four private functions to get a stock number, price and a quantity. I can successfully retrieve the user input but somehow the functions are not storing the input because my displayGroceryItem function doesn't do what it should which is to display what the user has entered (a stock number, a price and a quantity). The output does prompt a user for the input correctly but when the displayGroceryItem function is called, the fields are all display zero.

I've searched these forums and cplusplus.com but have come up short. Google keeps directing me to Chegg.com but it supposedly shows the solution which won't help me understand the concept at all.

I want to do this on my own and it's driving me nuts. I'm looking for tips or advice or even an "I can see the problem and it's at line #someLineNumber" but not finished code. Can anyone see how I goofed this up? Am I not calling the function correctly or did I not write the function correctly? I'm at a loss.

Any hints or advice is much appreciated!

The whole code follows:

#include "stdafx.h"
#include<iostream>
#include<string>
using namespace std;

class GroceryItem
{
    private:
        int stockNum;
        double price;
        int quantityInStock;
        double totalValue;
        // Three private functions to prompt for user input
        int getStockNum();
        double getPrice();
        int getQuantityInStock();
        double calculateTotal(); // Fourth private function to calculate total value (price times quantity in stock)
    public:
        void dataEntry(int, double, int);
        void setStockNum(int);
        void setPrice(double);
        void setQuantity(int);
        void displayGroceryItem(int, double, int, double); // Displays a GroceryItem’s values.
};
    int GroceryItem::getStockNum()
    {
    int itemNum = 0;
    stockNum = itemNum;
    int LOW = 1000;
    int HIGH = 9999;
    int stockNum = itemNum;
    cout << "Enter an item number >> ";
    cin >> itemNum;
    while(itemNum < LOW || itemNum > HIGH)
    {
        cout << "Invalid item number. Enter a valid item number between 1000 and 9999 >> ";
        cin >> itemNum;
    }
    return stockNum;        
}
double GroceryItem::getPrice()
{
    double itemPrice = 0;
    price = itemPrice;
    cout << "Enter the item price >> ";
    cin >> itemPrice;
    if(itemPrice < 0)
    {
        cout << "Invalid price. Enter a positive number >> ";
        cin >> itemPrice;
    }
    return price;
};
int GroceryItem::getQuantityInStock()
{
    int itemQuantity = 0;
    quantityInStock = itemQuantity;
    cout << "Enter a quantity >> ";
    cin >> itemQuantity;
    if(itemQuantity < 0)
    {
        cout << "Invalid quantity. Enter a positive number >> ";
        cin >> itemQuantity;
    }
    return quantityInStock;
};
double GroceryItem::calculateTotal()
{
    int itemQuantity = 0;
    double itemPrice = 0, totalValue;
    quantityInStock = itemQuantity;
    price = itemPrice;
    totalValue = itemQuantity * itemPrice;
    return totalValue;
}
void GroceryItem::setStockNum(int itemNum)
{
    stockNum = itemNum;
}
void GroceryItem::setPrice(double itemPrice)
{
    price = itemPrice;
    displayGroceryItem(stockNum, price, quantityInStock, totalValue);
}
void GroceryItem::setQuantity(int itemQuantity)
{
    quantityInStock = itemQuantity;
}
void GroceryItem::displayGroceryItem(int itemNum, double itemPrice, int itemQuantity, double grandTotal)
{
    this->stockNum = itemNum;
    this->totalValue = grandTotal;
    this->quantityInStock = itemQuantity;
    this->price = itemPrice;
    totalValue = quantityInStock * price;
    cout << "The stock number is #" << itemNum << endl <<
        "The price of the item is $" << itemPrice << endl <<
        "The quantity in stock is " << itemQuantity << endl <<
        "Total value is: $" << totalValue << endl;
}
void GroceryItem::dataEntry(int, double, int)
{
    GroceryItem::getStockNum();
    GroceryItem::getPrice();
    GroceryItem::getQuantityInStock();
};
int main()
{
    GroceryItem stock;
    int stockNum, quantityInStock, itemNum, quantity;
    double price, totalValue, itemPrice, grandTotal;

    stock.dataEntry(stockNum, price, quantityInStock); // call the dataEntry function
    stock.displayGroceryItem(stockNum, price, quantityInStock, totalValue); // display what the user entered from the dataEntry function
    return 0;
}
haldav
  • 127
  • 1
  • 13
  • you never set values on `stockNum`, `price`, etc... – Marc B Mar 15 '16 at 19:58
  • Without seeing the source of `GroceryItem::get…` it's hard to tell *anything* about the problem. But my guess is, that the `get…` functions don't actually read user input, but merely return the stored value (which is what *get* functions usually do). – datenwolf Mar 15 '16 at 19:58
  • 4
    Instead of reading tutorials on the internet and randomly flailing about on Google, have you considered _learning the language from a good book_? – Lightness Races in Orbit Mar 15 '16 at 19:58
  • Look at `main`. `stockNum`, `price`, `quantityInStock` and `totalValue` are all uninitialized. Then you pass those uninitialized values to `displayGroceryItem`. Then `displayGroceryItem` overwrites the grocery item's data with the (uninitialized) data it was passed. Then it displays the uninitialized data. – user253751 Mar 15 '16 at 19:59
  • `GroceryItem::getStockNum();` -- There is no need to prepend `GroceryItem::` to this and all of your other function calls within the `GroceryItem` class. I second what @BarryTheHatchet states if this is what you wound up writing. – PaulMcKenzie Mar 15 '16 at 20:04
  • @BarryTheHatchet: Do you have any recommendations for a good book? – haldav Mar 15 '16 at 20:14
  • 1
    Yes, a few! http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list – Lightness Races in Orbit Mar 15 '16 at 20:15
  • The book I'm reading is Object Oriented Programming Using C++ by Joyce Farrell and I don't see it in the list that was suggested. – haldav Mar 15 '16 at 20:23
  • Dangerous name for a book being used by a beginner. From the title it sounds like the author assumes you already know C++ and wish to apply object oriented principles to it. Not familiar with the book, but Amazon's description seems to back me up. – user4581301 Mar 15 '16 at 20:47
  • http://www.amazon.com/Object-Oriented-Programming-Using-Introduction/dp/1423902572/ref=dp_ob_title_bk – haldav Mar 15 '16 at 21:05
  • Interesting. I was directed to this one: http://www.amazon.com/Object-Oriented-Programming-Using-C/dp/0760050449 – user4581301 Mar 15 '16 at 21:07

1 Answers1

0

A quick walk-through in calling order to demonstrate what's going on and why it can never work.

int main()
{
    GroceryItem stock;
    int stockNum, quantityInStock, itemNum, quantity;
    double price, totalValue, itemPrice, grandTotal;

Up to here I have no problems, but the next line things go south

    stock.dataEntry(stockNum, price, quantityInStock); // call the dataEntry function

dataEntry is called with three parameters that will be used later. Let's look at dataEntry and how it uses the values passed in.

void GroceryItem::dataEntry(int, double, int)

The variables passed in are not used for anything. They are ignored and not set to any usable value. And even if they were used, they are all pass by value. This means dataEntry would operate on a local copy of the variables and the originals back in main would be unaffected.

{
    GroceryItem::getStockNum();

Pause and take a look into what getStockNum does.

int GroceryItem::getStockNum()
{
    int itemNum = 0;
    stockNum = itemNum;

Sets member variable stockNum to the current value of itemNum, or 0. It is important to note that stockNum and itemNum both refer to different locations in memory. At the moment they both contain the same value, 0, but either variable can be changed to a different number without affecting the other.

    int LOW = 1000;
    int HIGH = 9999;
    int stockNum = itemNum;

This creates a new local variable named stockNum that will hide the member variable stockNum and sets this stockNum to 0. And as above with stockNum and itemNum, these two stockNums refer to different locations in memory. Everything you do to this local stockNum will only affect this stockNum, and this stockNum will be destroyed at the end of the function. The member variable stockNum will be unchanged. When using multiple variables with the same name, only the inner most is directly visible.

    cout << "Enter an item number >> ";
    cin >> itemNum;

Reads a number from the user into itemNum. This will change the value of itemNum. It will not change either of the stockNums. As a side note, when you read from a data stream you need to test that you read a proper value. In this case itemNum is an int, so if you enter any value that doesn't not convert to an integer, the conversion will fail and the contents of itemNum will be undefined. There are a bunch of other gotchas you will need to read up on.

    while (itemNum < LOW || itemNum > HIGH)
    {
        cout
                << "Invalid item number. Enter a valid item number between 1000 and 9999 >> ";
        cin >> itemNum;
    }
    return stockNum;

Will always return 0 because that's the last value written to stockNum.

}

I'm stopping here because the remaining functions repeat the same mistakes. I recommend that the OP to do more reading of the language fundamentals before continuing. Particularly spend time on how memory is assigned and referenced, and the concepts of Scope, Pass by Reference, and Pass by Value.

user4581301
  • 33,082
  • 7
  • 33
  • 54
  • Also, OP needs to flush cout if they're not going to emit a newline. – James Youngman Mar 15 '16 at 22:27
  • @user4581301 - This is exactly what I needed. I was able to go back through my code and weed out the incorrect lines. It's working for me now. Thank you so much for the tutorial! – haldav Mar 16 '16 at 01:36