Declaring a 2d Array

Pages: 12
Can someone please tell me why it's telling me "a nonstatic member reference must be relative to a specific object"? I realize I'm not done here, but it's hard to continue when I can't even declare an array. This is my 3rd class and I'm still having trouble with declaring arrays. I've done it just like the book.


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
  #ifndef PRODUCT_H
#define PRODUCT_H

#include <fstream>

class Product
{
private:
	//Declare the array
	const int NUM_ROWS = 50;
	const int NUM_COLUMNS = 4;
	Product	inventory[NUM_ROWS][NUM_COLUMNS];	//Array with 50 rows and 4 columns

	//Initialize the array
	void initializeArray(Product inventory[NUM_ROWS][NUM_COLUMNS]);



public:



};

#endif	//PRODUCT_H 
Why are you trying to declare an array of Product in your Product definition? If you want an array of Product it should be external of the Product class.

Should the array be created in the implementation file for the class, or just before the class in the header file?
Maybe I should tell you what I'm trying to do. I have a text file full of 50 different products with an item number, description, price, and tax status. I am trying to initialize the array with this information.

<void Product::initializeArray(Product inventory[NUM_ROWS][NUM_COLUMNS])
{
ifstream inputFile;
int count = 0;

//Open the file.
inputFile.open("C:\\Users\\Beverly\\OneDrive\\School\\CISS 350\\Week1_GroceryStore\\Week1_GroceryStore\\Inventory.txt");

if (!inputFile) //If the file cannot open, exit gracefully.
{
cerr << "Error: File could not be opened." << endl;
exit(1);
}

//Initialize the array.
while (count < NUM_ROWS && inputFile >> inventory[NUM_ROWS][NUM_COLUMNS])
count++;

//Close the file.
inputFile.close();

//Display the array
cout << "Product Number " << setw(8) << "Description" << setw(15) << "Price" << setw(8) << "Tax Status" << endl;
cout << "______________________________________________________________________________________________________" << endl;
for (count = 0; count < NUM_ROWS; count++)
cout << inventory[NUM_ROWS][NUM_COLUMNS] << endl;
cout << endl;

return;
}>
Last edited on
Wait. I should create the product class without the array and create the array of products completely outside of the class, right? As in Main instead.
What is the purpose of the class?

Normally when you want an array of a class you define the array outside of the class interface, for example in main().
Thank you, I realize now I was starting all wrong. I'm fixing all this now. Sometimes I just need a kick in the head.
So if I have the class Product, which has the number, description, price, and tax status as members. When I initialize it, how do I use my data file and create the array?

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
class Product
{
private:
	//Variables
	int *inventory;			//Pointer to the array
	int numElements;		//Number of RoWS in the array
	int product_num;		//No more than 5 numbers
	string product_descr;	//Product description, no more than 12 characters with no embedded blanks
	double price;			//Price of the product
	char tax;				//T = Taxable, N = Not taxable

public:
	//Constructor
	Product(int, string, double, char);

	//To set the values
	void setProd_num(int);
	void setProd_Descrip(string);
	void setPrice(double);
	void setTax(char);

	//To return the values
	int getProd_num(int) const;
	string getProd_Descrip(int) const;
	double getPrice(int) const;
	char getTax(int) const;

	//Destructor
	~Product();
};
This is my start. I started with just initializing 1 product with default values, then commented it out. Then decided to do the array with default values, and then decided I'd rather go ahead and populate from my text file. Can I do this here?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Product::Product(int ROWS, int COLS)
{
	//char T;
	//product_num = 11111;		
	//product_descr = " ";	
	//price = 0.0;			
	//tax = T;
	inventory = new Product[ROWS][COLS];
	numElements = ROWS;

	for (int ndx = 0; ndx < ROWS; ndx++)
		inv[ndx] = 1111;
	for (int ndx = 0; ndx < ROWS; ndx++)
}
After typing all of this, I think I should go with my original commented out code and declare the array in main(). That's the right answer, right?

I should mention I'm trying to create an abstract array data type.
Last edited on
That's the right answer, right?

There is really no one right answer.

I should mention I'm trying to create an abstract array data type.

Okay, perhaps you could explain what you mean by an abstract array data type, and possibly explain why you think that is the best option for this application.

1
2
//Variables
	int *inventory;			//Pointer to the array 

I would really recommend you use a std::vector instead of the array.

1
2
3
4
Product::Product(int ROWS, int COLS)
{
	...
	inventory = new Product[ROWS][COLS];

Why do you need a multidimensional array of inventory? And by the way arrays require compile time constants for their sizes, the snippet above is not meeting this requirement.

By the way it looks to me like you need to step back and determine what information you need to adequately model your physical inventory. For example if your "Product" consists of multiple "Items" that could have different quantities you may need several classes.

For example a "simple" bicycle may have the following "Items"

1 frame
2 wheels
1 seat
1 chain
2 pedals
etc.

And you may have different assemblies for different end products, so what you need really depends on the complexity of what you're trying to model.


That's the right answer, right?

There is really no one "right" answer. There are many different ways to solve this problem.

I should mention I'm trying to create an abstract array data type.

It would probably help if you described in English what you mean by "abstract array data type" and also describe why you chose this "data type" for this assignment and how it will help solve the problem.

Thank you, everyone, I couldn't get back to this site last night, it was telling me the server was down. Anyways, I have made many changes to it. But now I'm thinking I'm wrong again. I'm thinking maybe just a single array instead of a 2d array. The reason for my choice is because of the instructions for my assignment which say, "The inventory information can be stored in an array of product records. Assume that the maximum number of products is 50, for purposes of writing this program. You should specify this data structure as an ADT, as described in the chapter; define and implement a set of operations to encapsulate it. The ADT should be tested using a test driver." And, after rereading this is when I decided I should do a single array of the product numbers. Now, if I do this, how will I find the associated information for the product code?

Here's my updated code (before switching to a single array):

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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
#include "Product.h"
using namespace std;

//Global variable
const double TAXamt = 0.075;  //The tax amount is 7.5%

//Function Prototype
int binarySearch(Product inventory[][], int, int);	//To search for the product to be purchased

int main()
{
	//Declare variable
	const int NUM_ROWS = 50;	//Number of rows for the array; 50 products total
	const int NUM_COLS = 4;		//Number of columns for the array:  product number, description, price, tax status
	Product inventory[NUM_ROWS][NUM_COLS];	//An array of products
	Product receipt[NUM_ROWS][NUM_COLS];	//An array for the receipt
	ifstream inputFile;
	ofstream outFile;
	int count = 0, num, quant, prods;
	double price, subtotal, total;
	string item;
	double itemPrice;
	char itemTax, taxable;

	
	//Open the file.
	inputFile.open("C:\\Users\\Beverly\\OneDrive\\School\\CISS 350\\Week1_GroceryStore\\Week1_GroceryStore\\Inventory.txt");
		
	if (!inputFile) //If the file cannot open, exit gracefully.
	{	
		cout << "Error: File could not be opened." << endl;
		exit(1);
	}
	
	//Initialize the array.
	for (int row = 0; row < NUM_ROWS; row++)
	{
		for (int col = 0; col < NUM_COLS; col++)
		{
			inputFile >> inventory[NUM_ROWS][NUM_COLS];
		}
	}
	
	//Close the file.
	inputFile.close();
	
	//Display the array
	cout << " Welcome to Wideman Grocery! " << endl;
	cout << "----------------------------------------" << endl;
	cout << endl;
	cout << "Product Number" << setw(15) << "Description" << setw(15) << "Price" << setw(8) << "Tax Status" << endl;
	cout << "----------------------------------------" << endl;
	
	for (count = 0; count < NUM_ROWS; count++) 
		cout << inventory[NUM_ROWS][NUM_COLS] << endl;
	
	cout << endl;
	cout << "----------------------------------------" << endl;
	cout << endl;

	//Determine how many products are being purchased
	cout << "How many products are being purchased:  ";
	cin >> prods;
	if (prods < 0)
	{
		cout << "Please enter a number greater than 0:  ";
		cin >> prods;
	}

	for (int i = 0; i < prods; i++)
	{
		cout << "Please enter the product number:  " << endl;
		cin >> num;

		cout << "Please enter the quantity to be purchased:  ";
		cin >> quant;

		//Search inventory array for the item
		int element = binarySearch(inventory[NUM_ROWS][NUM_COLS], NUM_ROWS, num);
		
		//If found, get product information					**************************************************What do I do here??  I want to get the product info stored in the array inventory
		item = inventory.getProd_Descr(element);
		itemPrice = inventory.getPrice(element);
		itemTax = inventory.getTax(element);

		//Calculates the tax
		if (taxable == 'T')
		{
			subtotal = (TAXamt)*(itemPrice * quant);
		}

		else //Non-taxable items
		{
			subtotal = (TAXamt)*(itemPrice * quant);
		}

		//Calculate the total for entire purchase.
		total += subtotal;

		//Add each product and info to the receipt
		for (int numProd = 0; numProd < prods; numProd++)
		{
			receipt.setProd_num(num);
			receipt.setProd_Descrip(item);
			receipt.setPrice(itemPrice);
			receipt.setTax(itemTax);
			//*************************************************************How will I add the quantity of each??
		}
	}

	//Print the receipt
	//Open the file
	outFile.open("C:\\Users\\Beverly\\OneDrive\\School\\CISS 350\\Week1_GroceryStore\\Week1_GroceryStore\\Receipt.txt");

	if (!outFile) //If the file cannot open, print receipt on the screen and exit gracefully.
	{
		cout << "Error: File could not be opened." << endl;
		cout << fixed << setprecision(2) << "Here is your receipt! Thanks for shopping at Wideman Grocery. " << endl;
		cout << "Product Number" << setw(15) << "Description" << setw(15) << "Price" << setw(8) << "Tax Status" << endl;
		cout << "--------------------------------------------------------------------------------------------------" << endl;

		for (count = 0; count < NUM_ROWS; count++)
			cout << receipt[NUM_ROWS][NUM_COLS] << endl;

		cout << "Thank you.  Have a nice day." << endl;
		exit(1);
	}

	outFile << fixed << setprecision(2) << "Here is your receipt! Thanks for shopping at Wideman Grocery. " << endl;
	outFile << "Product Number" << setw(15) << "Description" << setw(15) << "Price" << setw(8) << "Tax Status" << endl;
	outFile << "--------------------------------------------------------------------------------------------------" << endl;
	cout.setf(ios::left);

	for (count = 0; count < NUM_ROWS; count++)
		cout << receipt[NUM_ROWS][NUM_COLS] << endl;

	outFile << "TOTAL " << setw(60) << "$" << total << endl;
	outFile << "Thank you.  Have a nice day." << endl;

	//Close the file
	outFile.close();

	//Free Memory
	delete[] inventory;
	delete[] receipt;


	return 0;
}	//End of main()

//*****************************************************************************************
//Binary Search of the array to find the right product
int binarySearch(Product inventory[][NUM_COLS], int NUM_ROWS, int num)
{
	int first = 0,				//First array element
		last = NUM_ROWS - 1,	//Last array element
		middle,					//Midpoint of search
		position = -1;			//Position of search value
	bool found = false;			//Flag

	while (!found && first <= last)
	{
		middle = (first + last) / 2;	//Calculate midpoint
		if (inventory[NUM_ROWS][NUM_COLS] == num)	//If value is found at mid
		{
			found = true;
			position = middle;
		}
		else if (inventory[NUM_ROWS][NUM_COLS] > num)	//If value is in lower half
			last = middle - 1;
		else
			first = middle + 1;	//If value is in upper half
	}

	return position;
}	//End of binarySearch 
Here's the class:

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
#ifndef PRODUCT_H
#define PRODUCT_H

#include <iostream>
#include <string>
using namespace std;

class Product
{
private:
	//Variables
	int product_num;		//No more than 5 numbers
	string product_descr;	//Product description, no more than 12 characters with no embedded blanks
	double price;			//Price of the product
	char tax;				//T = Taxable, N = Not taxable

public:
	//Constructor
	Product();

	//To set the values
	void setProd_num(int);
	void setProd_Descrip(string);
	void setPrice(double);
	void setTax(char);

	//To return the values
	int getProd_num(int) const;
	string getProd_Descrip(int) const;
	double getPrice(int) const;
	char getTax(int) const;

	//Overload functions
	friend ostream& operator<<(ostream& os, const Product& prod);
	friend istream& operator>>(istream& os, const Product& prod);
};

#endif	//PRODUCT_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
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
#include <iostream>
#include <iomanip>
#include <string>
#include "Product.h"

using namespace std;

//Constructor
Product::Product()
{
	char T;
	product_num = 11111;		
	product_descr = " ";	
	price = 0.0;			
	tax = T;
}
//*******************************************************************************************************************************************************************
//Overload << operator to display Product
ostream& operator<<(ostream& os, const Product& prod)
{
	os << prod.getProd_num << setw(15) << prod.getProd_Descrip << setw(15) << prod.getPrice << setw(8) << prod.getTax;
	return os;
}
//*******************************************************************************************************************************************************************
//Overload >> operator to initialize Product array
istream& operator>>(istream& is, const Product& prod)
{
	is >> prod.setProd_num >> prod.setProd_Descrip >> prod.setPrice >> prod.setTax;
	return is;
}
//*******************************************************************************************************************************************************************
//To set the values
void Product::setProd_num(int num)
{
	if (num > 0 && num < 6)
		product_num = num;
	else
		cout << "Product number must be 5 digits." << endl;
}
//*******************************************************************************************************************************************************************
void Product::setProd_Descrip(string name)
{
	int size = name.size;
	if (size > 0 && size < 13)
		product_descr = name;
	else
		cout << "The product description cannot be longer than 12 characters." << endl;
}
//*******************************************************************************************************************************************************************
void Product::setPrice(double money)
{
	price = money;
}

void Product::setTax(char taxes)
{
	char T, N;
	if (taxes == T || taxes == N)
		tax = taxes;
	else
		cout << "The taxable status must be T for taxable or N for Non-taxable." << endl;
}
//*******************************************************************************************************************************************************************
//To return the values
int Product::getProd_num(int index) const
{
	return inventory[index];
}
//*******************************************************************************************************************************************************************
string Product::getProd_Descrip(int index) const
{
	return inventory[index];
}
//*******************************************************************************************************************************************************************
double Product::getPrice(int index) const
{
	return inventory[index];
}
//*******************************************************************************************************************************************************************
char Product::getTax(int index) const
{
	return inventory[index];
}
My arrays are not working and my get functions won't work as coded either. I'm still trying to think through all of this, but I'm going in circles at this point. A push in the right direction would be much appreciated! Thanks in advance!
Last edited on
 
	cout << " Welcome to Wideman Grocery! " << endl;

Ah, so you're trying to model a Grocery store inventory, nice to know.

inputFile.open("C:\\Users\\Beverly\\OneDrive\\School\\CISS 350\\Week1_GroceryStore\\Week1_GroceryStore\\Inventory.txt");

Another nice piece of information. Please post your sample input file.

1
2
3
4
5
6
private:
	//Variables
	int product_num;		//No more than 5 numbers
	string product_descr;	//Product description, no more than 12 characters with no embedded blanks
	double price;			//Price of the product
	char tax;				//T = Taxable, N = Not taxable 

Are the comments based on the assignment specifications?

Please post the actual assignment specification.



My arrays are not working and my get functions won't work as coded either. I'm still trying to think through all of this, but I'm going in circles at this point. A push in the right direction would be much appreciated! Thanks in advance!

Your class should be defined to hold the information for one product, so start with a small program to create and use a single instance of the class until you finish the class interface. Then converting to arrays should be fairly easy.

1
2
3
4
string Product::getProd_Descrip(int index) const
{
	return inventory[index];
}

Where and what is an inventory, and where was this array defined? I don't see any array named inventory in the class definition.

1
2
3
4
5
6
7
8
9
//Constructor
Product::Product()
{
	char T;
	product_num = 11111;		
	product_descr = " ";	
	price = 0.0;			
	tax = T;
}

You really should consider using constructor initialization lists with your constructor. And note you are using T uninitialized which means that tax it not properly initialized. Also since your product number has a limit on the number of digits you may want to consider using a string instead of the integer. Remember not all "numbers" must be stored using numeric values. Take your product number for example, if you store the value in a numeric variable you will probably have problems with products that start with zero (00100 would be stored as 100).

1
2
3
4
5
6
// Constructor using initialization list to initialize the variables.
// Using a string to hold the product_num and product descr, using a double for the price, and a bool for taxable (note the change from tax to taxable which is more descriptive for a bool value).
Product::Product() : product_num("00000"), product_descr("None"), price(0.0), taxable(false) 
{
    // Blank body.
}


I defined the array outside of the class in main(), based on someone's suggestion. I was trying to define the array inside the constructor at first but was not able to do it.

A sample of the input file:

10001 Gallon-Milk 1.99 N

The numbers go from 10001 - 10050.

So I need to turn taxable into a boolean with T = true and N = false.

How would I initialize the array with the constructor? Should it be single or multidimensional?

Assignment Specification:
You will write, run, and test a C++ program to simulate the operation of a grocery store checkout system. Your program should first build a data structure to contain information on all the products available in the store. Then the program should print the cash register receipt for each customer.
Input
The input for this program has two sources: the inventory information is input from a text file, and the customer transactions are input from the keyboard.

1. The information about each product carried by the store is listed on a single line in the inventory file "Invent.dat", in the following format:
<product number> <description> <price> <tax>
where <product number> is a five-digit positive (nonzero) integer, <description> is a string of at most 12 characters with no embedded blanks, <price> is a real number, and <tax> is a character ('T' if the product is taxable; 'N' if it is not taxable). The data in the inventory file is ordered from smallest to largest product number.
2. The customer transactions are input from the keyboard, in the following format:
<product number> <times>
where <product number> is as described above, and <times> is an integer in the range 1 to 100, indicating the quantity of this product desired. A zero input for <product number> indicates the end of the customer's order. (The store will soon be using a scanner to input the product number, but for now it is typed in by the cashier.)
Output
The program outputs should be written to a text file called "Receipts.out."
1. The inventory information is echo printed to the output file.
2. The cash register receipt for each customer is written to the output file. The receipts should be nicely formatted, with the product description (not the product number), number of items, item price, and total price for each product printed on a single line. At the end of each customer's order, the subtotal for all items, amount of tax on taxable items, and total bill should be printed, clearly labeled. (The tax rate is 7.5% for taxable items.)
Processing
1. The program first reads in all of the inventory information from file "Invent.in." echo printing the information to the output file.
2. The program then prompts the cashier to begin inputting the order for the first customer.
3. This customer's order is processed, and the receipt is printed to the output file.
4. After each customer's order is processed, the program should ask the cashier if another customer is to be processed. If the answer is 'Y', the program sets up to process the next customer; if the answer is 'N', the program terminates with a friendly message.
Error Checking
The following input errors are possible and should be handled by an exception class:

1. Duplicate <product number> in inventory file. Write an error message to the output file and skip the second entry.
2. <Product number> not in inventory file. Write an error message on the receipt, ignore that product number, and continue with the next item.
3. <Times> not in the specified range. Write an error message to the output file, ignore that line, and continue with the next item.
Example
From File "Invent.in":
11012 gallon-milk 1.99 N
11014 butter 2.59 N
11110 pie-shells 0.99 N
20115 laundry-soap 3.60 T
30005 homestyle-br 0.99 N

From keyboard (one customer):
11110 2
40012 3
20115 1
0

To "Receipts.out" file:
------------------------------------------------------
SEP 10, 1998 6:00 pm (* date and time optional *)
Customer 1
pie-shells 2 @ 0.99 1.98
*** item 40012 not in inventory ***
laundry-soap 1 @ 3.60 3.60 TX
Subtotal 5.58
Tax 0.27

Total 5.85
Data Structures
The inventory information can be stored in an array of product records. Assume that the maximum number of products is 50, for purposes of writing this program. You should specify this data structure as an ADT, as described in the chapter; define and implement a set of operations to encapsulate it. The ADT should be tested using a test driver.
Deliverables
• Your design (either object-oriented or top-down)
• A listing of the ADT
• A listing of the test driver for the ADT
• A listing of the test plan as input for the driver
• A listing of the output from the test driver
• A listing of your program
• A listing of your test plan as input to the program
• A listing of the output file

As you can tell from the spec, I am far from finished, I haven't even done the error checking parts yet.
I defined the array outside of the class in main(), based on someone's
suggestion. I was trying to define the array inside the constructor at first but
was not able to do it.

Remember class member functions are really designed to manipulate class member variables, they shouldn't know anything about the outside world.

I would expect your "get" functions to be defined more like:
1
2
3
4
5
6
...
	//To return the values
	int getProd_num() const;
	string getProd_Descrip() const;
	double getPrice() const;
	char getTax() const;


Notice the lack of parameters, you would just return the value held in the class member variable.


How would I initialize the array with the constructor? Should it be single or multidimensional?
Your program should first build a data structure to contain information on all the products available in the store. Then the program should print the cash register receipt for each customer.

You should define a single dimensional array outside the class and the array elements will be initialized with your default arguments automatically. You will then read your input data file to retrieve the information for each element of the array and use your "set" functions to set the values of the member variables with the values read. Since you're using an array you'll need to keep track of the number of products you read from the file.


The numbers go from 10001 - 10050.

No, look closer at your sample data file.
From File "Invent.in":
11012 gallon-milk 1.99 N
11014 butter 2.59 N
11110 pie-shells 0.99 N
20115 laundry-soap 3.60 T
30005 homestyle-br 0.99 N


Your product codes are described as:
where <product number> is a five-digit positive (nonzero) integer

So you can only assume that the values will be greater than zero and less than 100,000 (1 to 99999).

Remember your product class will hold the information for a single product. Your array will be external and the class will never know anything about this array, this is what makes it an Abstract Data Type, the data type (your product class) doesn't know or care about how many instances of the class exist it is very selfish, it is only concerned about the one and only one.


That sample data file came from the instructions and is not the file I am using. I created the numbers to go in order from low to high from 10001 - 10050, so it would be easier for me to test.

I guess I don't understand how a single array can populate 4 columns and 50 rows?
Last edited on
Pages: 12