Operator overloading woes: cin>>

Operator overloading seems to keep tripping me up. Here's my task (this is the same task as in my other topic, but since I'm asking about a different area, I felt it'd be best to make a new topic):
1.) The user types a gigantic, 40-digit number
2.) I cin it as a string (since int can't be that big)
3.) I turn that string into a character array
4.) I turn that character array into an int array
5.) I perform multiplication and/or addition on the array

I essentially have everything working - the addition and multiplication algorithms work, the conversion algorithms work, everything is good. The issue is just overloading the cin ">>" operator.

When I try to compile, I get this strange error:
HugeInteger.cpp:24:73: error: âstd::istream& HugeInteger::operator>>(std::istream&, const HugeInteger&)â must take exactly one argument

I call it strange, because when I make it one argument, it says I must take exactly two arguments!

I'm at a bit of a loss here. Anyone see what's wrong?

Here is my code:
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 <iostream>
using namespace std;

#include "HugeInteger.h"

HugeInteger::HugeInteger()
{
        for (int i = 0; i <= MAX2; i++)
                arr[i] = 0;
}

HugeInteger::HugeInteger(int op1[])
{
        for (int i = 0; i <= MAX2; i++)
                arr[i] = op1[i];
}

// friend
istream & HugeInteger::operator >> (istream & is, const HugeInteger & in)
{
        string num1;
        char cArray[in.MAX];

        int iArray[in.MAX];

          cin >> num1;

        num1.copy(cArray, num1.size(), 0);

        for (int i = 0; i < num1.size(); i++)
        {
                iArray[i] = in.atoi(cArray[i]);
                cout << cArray[i] << " . " << iArray[i] << endl;
        }
        cout << endl;


}


int HugeInteger:: atoi (char c)
{
        int i = c;
        i = i - 48;
        return (i);
}

ostream & operator << (ostream & os, const HugeInteger & out)
{
        bool eraseZeroes = true;

        for (int i = 0; i <= out.MAX2; i++)
        {
                if (out.arr[i] != 0 || eraseZeroes == false)
                {
                        os << out.arr[i];
                        eraseZeroes = false;    // The boolean variable eraseZeroes is used to erase superflous zeroes (like 0009 instead of 9)
                }
        }
        return (os);
}

const HugeInteger & HugeInteger::operator + (const HugeInteger& right)
{
        HugeInteger result;

        add(right.arr);

        return (*this);
}

void HugeInteger::add(const int op2[])
{
        int carry;

        for (int i = MAX2; i >= 0; i--)
        {
                arr[i] = arr[i] + op2[i] + carry;

                carry = 0;

                while (arr[i] >= 10)
                {
                        arr[i] -= 10;
                        carry++;
                }

        }
}

const HugeInteger & HugeInteger:: operator * (const HugeInteger& rightside)
{
        HugeInteger resultmult;

        int mult_array[resultmult.MAX] = {0};
        int addzero_ctr;
        int lastDigit;
        int firstDigit;
        const int num = 10;
        int product_holder;
        for (int m = (resultmult.MAX2); m >= 0; m--) // This 'for' loop essentially sums together the results of the below 'for' loop to carry out the multiplication
        {
                for (int i = (resultmult.MAX2); i >= 0; i--) // This 'for' loop multiplies all of op1 by the last digit of op2 and puts the value into result[i]
                {
                        product_holder = arr[i] * rightside.arr[m];
                        arr[i] = product_holder;
                        lastDigit = product_holder % num;

                        resultmult.arr[i] = firstDigit;

                        product_holder -= lastDigit;
                        firstDigit = product_holder / num;

                        resultmult.arr[i] += lastDigit;
                }

                if (addzero_ctr != 0)                                   // solution to below
                {
                        for (int i = 0; i <= (resultmult.MAX2 - addzero_ctr); i++)//This is a lot of overhead when addzero_ctr = 0
                        {
                                arr[i] = resultmult.arr[i+addzero_ctr];
                        }
                }


                for (int i = addzero_ctr; i > 0; i--) // Since we need to carry a zero during multiplication, the contents of the array must shift to the left to make room for the zeroes
                {
                        resultmult.arr[resultmult.MAX - i] = 0;
                }

                add(mult_array);

                addzero_ctr++;
                for (int i = 0; i <= resultmult.MAX2; i++)
                {
                        mult_array[i] = arr[i];
//              cout << "mult[i] = " << mult_array[i] << endl;  /./   Use this comment section to check what result[i] is immediately before m is decremented
                }

        }
}


And here's my .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
#ifndef HugeInteger_h
#define HugeInteger_h

#include <string>

//Course class definition
class HugeInteger
{
        public:
                HugeInteger();
                HugeInteger(int[]);

                const HugeInteger & operator + (const HugeInteger&);
                const HugeInteger & operator * (const HugeInteger&);

                friend ostream & operator << (ostream&, const HugeInteger&);
                friend istream & operator >> (istream&, HugeInteger&);

                int atoi(char);
                void display();

         private:
                void add(const int[]);

                static const int MAX = 40;
                static const int MAX2 = 39; // Typing (MAX - 1) is tiresome

                int arr[MAX];
};
#endif 
Remove HugeInteger:: and const from line 19 in the source file.
¿what does num1.copy(cArray, num1.size(), 0); do?


By the way, your operators have weird behaviour.
1
2
HugeInteger a,b,c;
c = a+b; //¡¿modifies `a'?! 
This line
in.arr[i] = in.atoi(in.arr[i]);
you probably meant to write
in.arr[i] = in.atoi(cArray[i]);.

You don't really need cArray because you can use num1 directly.
in.arr[i] = in.atoi(num1[i]);

After this change you will notice that the digits will be written to the left most positions so you end up with very large numbers with many zeroes at the end but you can probably work it out.

operator>> should also return is.
Haha, I actually deleted my post because I fixed everything up to the point where you said I "can probably work it out".

I'm trying to work out now. Hopefully I'll get it, if not I'll post again.

Thanks for the help!
Well, this is strange.

Here's the change I made to my function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
istream & operator >> (istream & is, HugeInteger & in)
{
        string num1;
        char cArray[in.MAX];


//      int iArray[in.MAX];

        cout << "enter number plox\n";
        cin >> num1;
        cout << "num1 = " << num1 << endl;
        cout << "size of integer is " << num1.size() << endl;

        num1.copy(cArray, num1.size(), 0);

        for (int i = in.MAX2; i > (in.MAX - num1.size()); i--)
        {
                in.arr[i] = in.atoi(num1[i]);
        //      cout << cArray[i] << " . " << iArray[i] << endl;
        }
        cout << endl;
        return (is);
}


My logic was to alter the "for loop" so that the input would start from the end, a method I have used before with success.

Yet my output is once again nonsense!

I've tried playing around, but I can't see what's wrong here. It seems to me that my problem should be fixed....

Here's the ouput:

enter number plox:
43
num1 = 43
size of integer is 2

enter number plox:
5
num1 = 5
size of integer is 1

num1 = -480
num2 = -1
object: -480
arr: -1433646464
The answer is: -8-1433646464
If you do like that i will be out of bounds in num1.
But....how?

'i' starts at 39, goes through the loop, decreases by 1, and then repeats until it's no longer greater than '39 - (number of digits in integer)'

At what point does num1[i] go out of bounds??
num1[i] is out of bounds if i >= num1.size().
But if I want the 40th entry of the array to equal the last digit of the integer, and the integer is only, let's say, 5 digits long, wouldn't 'i' have to equal 39, which is greater than 5?
Yes, that's the problem. You should not use the same index to both in.arr and num1.
Ah! Now I see. Thank you!

But - this is so frustrating!!!!!!!! - when I run the function it gives me the wrong answer!

This is how I corrected the problem:
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
istream & operator >> (istream & is, HugeInteger & in)
{
        string num1 = " ";
        char cArray[in.MAX];
        int bound;

//      int iArray[in.MAX];

        cout << "enter number plox\n";
        cin >> num1;
        cout << "num1 = " << num1 << endl;
        cout << "size of integer is " << num1.size() << endl;

        num1.copy(cArray, num1.size(), 0);

        bound = in.MAX2;
        bound -= num1.size();
        cout << "BOUND = " << bound << endl;

        for (int i = in.MAX2; i > bound; i--)
        {
                int m = 0;
                in.arr[i] = in.atoi(num1[m]);
                m++;
                cout << cArray[i] << " . " << num1[i] << endl;
        }
        cout << endl;
        return (is);
}


This is my Main function:

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
#include <iostream>
using namespace std;

const int MAX = 40;

#include "HugeInteger.h"
int main()
{
        int op1[MAX] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,2,2,0};
        int op2[MAX] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,1,0};

        char op;
        op = '+';


        HugeInteger num1;
        HugeInteger num2;

        cin >> num1;
        cin >> num2;

        cout << "num1 = " << num1 << endl;
        cout << "num2 = " << num2 << endl;

        HugeInteger object(num1);
        HugeInteger arr(num2);



//      object.create_array(num1, num2, op1, op2);
        cout << "object: " << object << endl;
        cout << "arr: " << arr << endl;

        if (op == '+')
                arr = arr + object;
        else
                arr = arr * object;

        cout << "The answer is: " << arr << endl;

        return 0;

//      object.display();
}


This is the output:

enter number plox
4
num1 = 4
size of integer is 1
BOUND = 38
.

enter number plox
6
num1 = 6
size of integer is 1
BOUND = 38
.

num1 = 4
num2 = 6
object: 4
arr: 6
The answer is: 64



Again, I don't see how this is happening??
You forgot to initialize carry in add.

You need to define m outside the loop, otherwise it will not work if you have more than one digit because m is always 0 when you use it.
Last edited on
Thanks a lot!

I initialized add to zero, I defined m outside the loop (makes sense...I can't believe I didn't see that), and, believe it or not, it STILL isn't adding the numbers correctly!!!

Is it possible that I need to initialize the cArray? I tried making it:
char cArray[in.MAX] = {' '};
But, although that compiled, I still got nonsense answers.

This is the output:
4
num1 = 4
size of integer is 1
BOUND = 38
.
.

enter number plox
5
num1 = 5
size of integer is 1
BOUND = 38
.
.

num1 = -484
num2 = -485
object: -484
arr: -485
The answer is: -969
Okay, I found out that I had " >= bound" when it should be " > bound"

I fixed that error, but of course it still doesn't add properly (though now it's in the same ballpark!)

Here's my whole function:
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
istream & operator >> (istream & is, HugeInteger & in)
{
        string num1 = " ";
        char cArray[in.MAX] = {' '};
        int bound = 0;

//      int iArray[in.MAX];

        cout << "enter number plox\n";
        cin >> num1;
        cout << "num1 = " << num1 << endl;
        cout << "size of integer is " << num1.size() << endl;

        num1.copy(cArray, num1.size(), 0);

        bound = in.MAX2;
        bound -= num1.size();
        cout << "BOUND = " << bound << endl;


        int m = 0;
        for (int i = in.MAX2; i > bound; i--)
        {
                in.arr[i] = in.atoi(num1[m]);
                m++;
                cout << cArray[i] << " . " << num1[m] << endl;
        }
        cout << endl;
        return (is);
}


And here's some output:
78
num1 = 78
size of integer is 2
BOUND = 37
. 8
.

enter number plox
22
num1 = 22
size of integer is 2
BOUND = 37
. 2
.

num1 = 87
num2 = 22
object: 87
arr: 22
The answer is: 109
GOT IT!

Haha, m had to be set to the size of the integer, not zero. That's why it was switching them around.

Actually, set to the size of the integer minus one since arrays are zero-based.

Finally got this little troublemaker.

Thank you so much to everyone who helped me, now I have an addition function that is actually working!

Thank you so much!
Topic archived. No new replies allowed.