question regarding user input of objects and storing them dynamically

Basically my code is supposed to take in money objects such as 2.54, 3.05 and keep going until user types in 0.0. After, it finds the sum of all the objects and finds the median. However, I had an issue during runtime, shown in the output below.

Enter the expenditure record (e.g., $1.95, coffee, enter 0.0 to end):$8.45
Sorted list of expenditure:
The total is $0.0(ninety and0/100
The median is 0.0.

Basically my code is supposed to take in money objects such as 2.54, 3.05 and keep going until user types in 0.0. After, it finds the sum of all the objects and finds the median. However, I had an issue during runtime. enter image description here

Enter the expenditure record (e.g., $1.95, coffee, enter 0.0 to end):$8.45
Sorted list of expenditure:
The total is $0.0(ninety and0/100
The median is 0.0.

I'm pretty sure the issue is with the istream operator as no input seems to have been taken (particularly in main.cpp "cin >> arr[arr_len]), so I won't be adding any of the other functions. The issue I think is, I am not actually storing the objects anywhere in the istream operator. I think a solution would be to add another dynamic array to the private section of the class, but I would rather avoid doing this due to need to redefine destructors, constructors, etc. Any ideas on how I should store the objects? Any help is appreciated.

lab2.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
#ifndef LAB2_H
#define LAB2_H 
#include <iostream>
#include <string>
#include <cstdlib>

using namespace std;

class DollarAmount
{
    int dollar, cents;
    int maxsequence = 0;



    public:
        DollarAmount(int num1 = 0, int num2 = 0);

        int getDollar() const { return dollar; };

        int getCent() const { return cents; };

        int getmaxsequence() const { return maxsequence; };

        friend istream& operator >> (istream& ins, DollarAmount& arg);

        friend ostream& operator << (ostream& out, const DollarAmount& arg);

        friend DollarAmount operator + (const DollarAmount& arg1, const DollarAmount& arg2);

        friend DollarAmount operator / (const DollarAmount& arg1, const DollarAmount& arg2);

        friend bool operator > (const DollarAmount& arg1, const DollarAmount& arg2);

        void sortobjects(DollarAmount a[], int size);

        void searchobjects(DollarAmount a[], int size);

        //All of the below functions are from lab 1

        void converter1(string array1[], string array2[], string array3[], int x);

        void converter2(int y);


};

#endif 


lab2.cpp
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
istream& operator >> (istream& ins, DollarAmount& arg)
{
    int num1 = 0;
    int num2 = 0;
    char ch;
    bool wrongInput = false;

    ins >> num1 >> ch >> num2;


    do
    {
        if (wrongInput == true)
        {
            cout << "Enter the expenditure record (e.g., $1.95, coffee, enter -1 to end):$";
            ins >> num1 >> ch >> num2;
        }

        else if (num1 == 0 && num2 == 0)
            exit(1); // to quit program
        else if (cin.fail() || num1 < 0 || num1 > 9999 || num2 > 99) //in case the above fails, e.g., ten dollor five cents...
        {
            cout << "Wrong input types. Try again:\n";
            cin.clear(); //clear the error flags in cin 
            cin.ignore(2048, '\n'); //ignore everthing in the input buffer, up to 2048 char, 
            //up to the newline char =< ignore the rest of the line
            wrongInput = true;
        }
        else
            wrongInput = false;
    } while (wrongInput == true || num1 < 0 || num1 > 9999 || num2 > 99); // if input false ask for input again



    arg.maxsequence = arg.getmaxsequence() + 1;
    return ins;
}


main.cpp
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 <string>
#include <cstdlib>
#include "lab2.h"

using namespace std;

const int INIT_SIZE = 10;
const int a = 9;
const int b = 10;
const int c = 8;

int main()
{
    string one[a] = { "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" };
    string two[b] = { "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen" };
    string three[c] = { "twenty", "thirty", "fourty", "fifty", "sixty", "seventy", "eighty", "ninety" };

    DollarAmount* arr = new DollarAmount[INIT_SIZE];
    DollarAmount* ptr = NULL;
    int arr_size = INIT_SIZE;
    int arr_len = 0; // actual number of objects stored in it , also the index
      // of next free slot in arr

    bool lastInput = false;

    do 
    {
        if (arr_len == arr_size)
        { // the array is full, need to grow! 

           //allocate an array double the cur_size
            ptr = new DollarAmount[arr_size * 2];

            //copy each element in arr into the new array that ptr points to... 
            // Todo: please figure out how to do this...(hint: use a for loop)
            for (int i = 0; i < arr_size; i++)
            {
                ptr[i] = arr[i];
            }

            //now we delete the current arr
            delete[] arr;
            arr = ptr;
            arr_size = arr_size * 2;
        }

        cout << "Enter the expenditure record (e.g., $1.95, coffee, enter 0.0 to end):$";
        cin >> arr[arr_len];  //read in a dollar amount from cin we will allow input such as 0.0

        //If the last read dollar amount is 0.0, then it's the end 
        if (arr[arr_len].getDollar() == 0 && arr[arr_len].getCent() == 0)
            lastInput = true;
        else //we only increment arr_len for input that's not 0.0
            arr_len++;


    } while (lastInput == false);

    DollarAmount total, temp; 
    total = arr[0] + arr[1];
    //A loopt to add all DollarAmount up, and display the total 
    for (int i = 2; i < arr_len; i++)
    {
        total = total + arr[i];
    }
    //Call Sort function to sort the array of DollarAmount 

    //Display the sorted array, and the median 
    cout << "Sorted list of expenditure:" << endl;
    temp.sortobjects(arr, arr_len);

    //cout << "The total is $" << total.getDollar() << "." << total.getCent() << 
    cout << "The total is $" << total << "(";
    temp.converter1(one, two, three, total.getDollar());
    cout << "and"; 
    temp.converter2(total.getCent());
    cout << "The median is ";
    temp.searchobjects(arr, arr_len);
    cout << "." << endl;
    cout << "Bye!";
    return 0;
}
The issue I think is, I am not actually storing the objects anywhere in the istream operator.
Yes, the solution is much simpler than you think it. Because the operator>> is a friend you have already access to the private parts of the class. So just add e.g.:
1
2
3
4
    arg.dollar = num1;
    arg.cents = num2;
    arg.maxsequence = arg.getmaxsequence() + 1; // You already set the private variable maxsequence
    return ins;


I suggest that you store just cents. That would make calculating easier.
The main issue in your code is you’ve written to much before testing it.
Believe or not, adding functionalities one by one is a more efficient programming style compared to writing down a lot of declarations, or a anyway a lot of lines of code, without performing any test.

If you want your class to manage the user input (I’m not sure this is the best option), then your main() shouldn’t. On the other hand, if you manage the user input in a separate function, than your class should just accept the data as already checked.

Don’t duplicate the code (DRY --> don’t repeat yourself).
Have a look: main() starts a loop to accept the user input and calls the overloaded operator>>(), which starts another loop… to accept the user input!

This forces you to take debatable decisions.
When the user types 0.0, this should only causes the loop to break.
But in your code:
1
2
else if (num1 == 0 && num2 == 0)
    exit(1); // to quit program 

There’s no reason to exit the program here.


- - -
My advice is to break main() into functions.
- The block which makes the C-style arrays grow would fit very well in a separate functions (however using std::vectors would save you a lot of troubles).

- The block where you ask the user for input should be a separate function.

Do start with a lightweight frame, add small blocks of code together with debugging tests and compile often. IMHO.

Happy coding!
Thanks for the help I am removing redundancies, fixing many other errors, and added the below (its a requirement from my assignment to have dollar and cent as separate variables and to use dynamic arrays instead of vectors)

arg.dollar = num1;
arg.cents = num2;
arg.maxsequence = arg.getmaxsequence() + 1; // You already set the private variable
return ins;

Now I am able to input more than one inputs however, they still do not seemed to be stored, as shown below. Ignoring the syntax of the spacing, the sorted list fails to display and the total is wrong as well. So the issue still with the input, output, sort, sum functions which I will add below.

Enter the expenditure record (e.g., $1.95, coffee, enter 0.0 to end):$8.45
Enter the expenditure record (e.g., $1.95, coffee, enter 0.0 to end):$45.03
Enter the expenditure record (e.g., $1.95, coffee, enter 0.0 to end):$2.03
Enter the expenditure record (e.g., $1.95, coffee, enter 0.0 to end):$0.0
Sorted list of expenditure:
The total is $1.0oneand0/100
The median is 0.0.
Bye!




lab2.cpp
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
#include <iostream>
#include <string>
#include <cstdlib>
#include "lab2.h"

using namespace std;


DollarAmount::DollarAmount(int num1, int num2)
{
	dollar = num1;
	cents = num2;
}

istream& operator >> (istream& ins, DollarAmount& arg)
{
	int num1 = 0;
	int num2 = 0;
	char ch;
	bool wrongInput = false;
	
	ins >> num1 >> ch >> num2;
	

	do
	{
		if (wrongInput == true)
		{
			cout << "Enter the expenditure record (e.g., $1.95, coffee, enter -1 to end):$";
			ins >> num1 >> ch >> num2;
		}
		
		else if (cin.fail() || num1 < 0 || num1 > 9999 || num2 > 99) //in case the above fails, e.g., ten dollor five cents...
		{
			cout << "Wrong input types. Try again:\n";
			cin.clear(); //clear the error flags in cin 
			cin.ignore(2048, '\n'); //ignore everthing in the input buffer, up to 2048 char, 
			//up to the newline char =< ignore the rest of the line
			wrongInput = true;
		}
		else
			wrongInput = false;
	} while (wrongInput == true || num1 < 0 || num1 > 9999 || num2 > 99); // if input false ask for input again
	
	
	arg.dollar = num1;
	arg.cents = num2;
	arg.maxsequence = arg.getmaxsequence() + 1;
	return ins;
}

ostream& operator << (ostream& out, const DollarAmount& arg)
{
	out << arg.getDollar() << "." << arg.getCent();
	return out;
}

bool operator > (const DollarAmount& arg1, const DollarAmount& arg2)
{
	DollarAmount temp;
	string sa, sb, sc, sd, s1, s2;
	int a = arg1.dollar;
	int b = arg1.cents;
	int c = arg2.dollar;
	int d = arg2.cents;
	double num1, num2;

	sa = to_string(a);
	sb = to_string(b);
	sc = to_string(c);
	sd = to_string(d);

	s1 = sa + sb;
	s2 = sc + sd;

	num1 = atoi(s1.c_str()) / 100;
	num2 = atoi(s2.c_str()) / 100;

	if (num1 > num2)
		return true;
	else
		return false;
}

void DollarAmount::sortobjects(DollarAmount a[], int size)
{
	int i;
	int last = size - 1;  //point to the index of last element in unsorted part of the array 

	for (int pass = 0; pass < size; pass++)
	{
		//a[0]...a[last] is not sorted 
		//repeated bubble the largest element in this range to the end ... 
		for (i = 0; i <= last - 1; i++)
		{
			if (a[i] > a[i + 1])
			{
				//swap 
				DollarAmount tmp;
				tmp = a[i + 1];
				a[i + 1] = a[i];
				a[i] = tmp;
			}
		}
		//at this point, the largest element in a[0...last] is stored in a[last]

		//unsorted part is now a[0...last-1]
		last = last - 1;
	}
}


DollarAmount operator + (const DollarAmount& arg1, const DollarAmount& arg2)
{
	DollarAmount temp;
	string sa, sb, sc, sd, s1, s2, ssum;
	int a = arg1.dollar;
	int b = arg1.cents;
	int c = arg2.dollar;
	int d = arg2.cents;
	double num1, num2, sum;

	sa = to_string(a);
	sb = to_string(b);
	sc = to_string(c);
	sd = to_string(d);

	s1 = sa + sb;
	s2 = sc + sd;

	num1 = atoi(s1.c_str()) / 100;
	num2 = atoi(s2.c_str()) / 100;

	sum = num1 + num2;
	ssum = to_string(sum);

	int index = ssum.find(".");
	temp.dollar = atoi(ssum.substr(0, index).c_str());
	temp.cents = atoi(ssum.substr(index+1, ssum.length()).c_str());

	return temp;
}

bool operator > (const DollarAmount& arg1, const DollarAmount& arg2)
{
	DollarAmount temp;
	string sa, sb, sc, sd, s1, s2;
	int a = arg1.dollar;
	int b = arg1.cents;
	int c = arg2.dollar;
	int d = arg2.cents;
	double num1, num2;

	sa = to_string(a);
	sb = to_string(b);
	sc = to_string(c);
	sd = to_string(d);

	s1 = sa + sb;
	s2 = sc + sd;

	num1 = atoi(s1.c_str()) / 100;
	num2 = atoi(s2.c_str()) / 100;

	if (num1 > num2)
		return true;
	else
		return false;
}

void DollarAmount::converter2(int y)
{
	cout << y << "/100" << endl;
}


main.cpp
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
*
Victor Nath
1/26/20
Lab#2
*/

#include <iostream>
#include <string>
#include <cstdlib>
#include "lab2.h"

using namespace std;

const int INIT_SIZE = 10;
const int a = 9;
const int b = 10;
const int c = 8;

int main()
{
    string one[a] = { "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" };
    string two[b] = { "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen" };
    string three[c] = { "twenty", "thirty", "fourty", "fifty", "sixty", "seventy", "eighty", "ninety" };

    DollarAmount* arr = new DollarAmount[INIT_SIZE];
    DollarAmount* ptr = NULL;
    int arr_size = INIT_SIZE;
    int arr_len = 0; // actual number of objects stored in it , also the index
      // of next free slot in arr

    bool lastInput = false;

    do 
    {
        if (arr_len == arr_size)
        { // the array is full, need to grow! 

           //allocate an array double the cur_size
            ptr = new DollarAmount[arr_size * 2];

            //copy each element in arr into the new array that ptr points to... 
            // Todo: please figure out how to do this...(hint: use a for loop)
            for (int i = 0; i < arr_size; i++)
            {
                ptr[i] = arr[i];
            }

            //now we delete the current arr
            delete[] arr;
            arr = ptr;
            arr_size = arr_size * 2;
        }

        cout << "Enter the expenditure record (e.g., $1.95, coffee, enter 0.0 to end):$";
        cin >> arr[arr_len];  //read in a dollar amount from cin we will allow input such as 0.0

        //If the last read dollar amount is 0.0, then it's the end 
        if (arr[arr_len].getDollar() == 0 && arr[arr_len].getCent() == 0)
            lastInput = true;
        else //we only increment arr_len for input that's not 0.0
            arr_len++;


    } while (lastInput == false);

    DollarAmount total, temp; 
    total = arr[0] + arr[1];
    //A loopt to add all DollarAmount up, and display the total 
    for (int i = 2; i < arr_len; i++)
    {
        total = total + arr[i];
    }
    //Call Sort function to sort the array of DollarAmount 
     //Call Sort function to sort the array of DollarAmount 
    temp.sortobjects(arr, arr_len);
    //Display the sorted array, and the median 
    cout << "Sorted list of expenditure:" << endl;
    for (int i = 0; i < arr_len; i++)
    {
        cout << arr[i] << endl;
    }

    cout << "The total is $" << total.getDollar() << "." << total.getCent();
    cout << " (";
    temp.converter1(one, two, three, total.getDollar());
    cout << " and "; 
    temp.converter2(total.getCent());
    cout << ")" << endl;
    cout << "The median is ";
    temp.searchobjects(arr, arr_len);
    cout << "." << endl;
    cout << "Bye!";
    return 0;
   
}
Last edited on
update I have fixed: my issue turns out the issue was simple, needing a loop to output the array of sorted objects. Still working out some minor bugs but thanks for the help everyone!
Why not:
1
2
3
4
5
6
bool operator<(const DollarAmount& arg1, const DollarAmount& arg2)
{
    int cents1 = arg1.dollar * 100 + arg1.cents;
    int cents2 = arg2.dollar * 100 + arg2.cents;
    return cents1 < cents2;
}

And similarly for operator>.

I would probably just store cents and convert to/from dollars and cents for input/output.
Last edited on
Topic archived. No new replies allowed.