Create a class called Complex for performing arithmetic with complex numbers.

I have this assignment: Create a class called Complex for performing arithmetic with complex numbers. Complex numbers have the form:

realPart + imaginaryPart * i

where i is

√-1

Use double variables to represent the private data of the class. Provide a constructor that enables an object of this class to be initialized when it’s declared. The constructor should contain default values of (1,1) i.e. 1 for the real part and 1 for the imaginary part. Provide public member functions that perform the following tasks:

(a) add – Adds two Complex numbers: The real parts are added together and the imaginary parts are added together.
(b) subtract – Subtracts two Complex numbers. The real part of the right operand is subtracted from the real part of the left operand, and the imaginary part of the right operand is subtracted from the imaginary part of the left operand.
(c) toString – Returns a string representation of a Complex number in the form (a,b), where a is the real part and b is the imaginary part.

Write a main program to test your class. Your program should prompt the user to enter two Complex numbers. If the user hits enter without entering anything, then the default value of (1,1) used by the default constructor should be used. It should then print out the sum and difference of the two Complex numbers entered. The following is a sample run:

Enter a Complex number with the real and imaginary parts separated by a comma: 4,5
Enter a Complex number with the real and imaginary parts separated by a comma: 3,2

The sum of the two complex numbers is (7,7) and the difference is (1,3).

Another sample run would be:

Enter a complex number with the real and imaginary parts separated by a comma:
Enter a complex number with the real and imaginary parts separated by a comma: 3,2

The sum of the two Complex numbers is (4,3) and the difference is (-2,-1).

I created my code using char* but my build fails with the LNK ERRORS error LNK2019: unresolved external symbol _main referenced in function "int __cdecl invoke_main(void)" (?invoke_main@@YAHXZ)and fatal error LNK1120: 1 unresolved externals.

My instructer said my complex looked good but suggested that I change the char* to a string or cout output because char* is not part of the standard C++ so that could be creating the issues. How would I go about doing that with out starting over? Also, to solve the LNK errors where would the appropriate space be to place the MAIN? I tried placing it right after the namespace std; but that just created more errors.

As you can see my knowledge of coding is pretty minimal so if you could break it down Barney style for me I would greatly appreciate it.

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

class complex
{
private: double real_part; double img_part;
public: complex(double r = 1, double i = 1)
{
real_part = r; img_part = i;
};

char* toString();
void set_comp_No(double r, double i);
complex add(complex);
complex subtract(complex);
complex multiply(complex);
};
char* complex::toString()
{
char* c = new char[100];
if (img_part >= 0) sprintf_s(c, sizeof(c), "%ld+%ldi", (long)real_part, (long)img_part);
else sprintf_s(c, sizeof(c), "%ld %ldi", (long)real_part, (long)img_part);
return c;
}

void complex::set_comp_No(double r, double i)
{
real_part = r; img_part = i;
}

complex complex::add(complex x)
{
complex z;
z.real_part = real_part + x.real_part;
z.img_part = img_part + x.img_part;
return z;
}
complex complex::subtract(complex x)
{
complex z;
z.real_part = real_part - x.real_part;
z.img_part = img_part - x.img_part;
return z;
}
complex complex::multiply(complex x)
{
complex z;
z.real_part = real_part * x.real_part;
z.img_part = img_part * x.img_part;
return z;
}



char* is unrelated to missing main. where is the main function defined? C++ demands a main() function unless it is a library, which is compiled differently and does not give a runnable program. main can be anywhere, but top or bottom of main is usual, so its not too hard to find. If at bottom, it can see everything without prototypes, if at top, you need protos. You should use string not char* unless you have weird circumstances, he is correct, but its not the error. Char* absolutely is standard in c++, but its inherited from C and not usually a good thing to have. If main gives you errors, put it in and show us what you did there, we can fix. namespace std is bad practice, but handy for now, just be aware at least.


please use code tags <> in the editor.

1
2
3
4
5
6
7
8
9

string  toString();

string complex::toString()
{
string c;
 c+= to_string(real_part)+ " + " + to_string(imag_part) +"i"; //etc as you see fit
  return c;
}


also please try not to use standard c++ names or extremely similar unless forced to by requirements. c++ has a complex type and a tostring function, so something else (to_text?) and class imaginary{} could be a little less of an explosion esp since you pulled in namespace std; --- you are going to collide with existing names if careless using these practices.
Last edited on
Hey SeaMist,

When posting code, use code tags to maintain indentation.

In place of sprintf, you could use ostringstream.

And you should be able to change just the real or imaginary part of a complex number individually. I wonder if it would actually be best to just make them public.

I put a little example of operator overloading in.

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
#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>

using namespace std;

struct Complex
{
    double real;
    double imag;

    Complex(double r = 0, double i = 0)
        : real(r), imag(i) { }

    string toString() const;
    Complex add(Complex) const;
    Complex subtract(Complex) const;
    Complex multiply(Complex) const;

    Complex& operator+=(const Complex& x) {
        real += x.real;
        imag += x.imag;
        return *this;
    }

    // Pass lhs by value, modify it, and pass it thru.
    friend Complex operator+(Complex lhs, const Complex& rhs) {
        return lhs += rhs;
    }
};

ostream& operator<<(ostream& out, const Complex& x) {
    return out << x.toString();
}

string Complex::toString() const {
    ostringstream out;
    // showpos "shows positive" signs, not just negative.
    out << real << showpos << imag << 'i';
    return out.str();
}

Complex Complex::add(Complex x) const {
    return Complex(real + x.real, imag + x.imag);;
}

Complex Complex::subtract(Complex x) const {
    return Complex(real - x.real, imag - x.imag);;
}

// I don't think this is how you multiply complex numbers!
Complex Complex::multiply(Complex x) const {
    return Complex(real * x.real, imag * x.imag);;
}

int main() {
    Complex b(1, 2), c(-2, 3);
    cout << b.add(c) << '\n';
    cout << b + c << '\n';
}

1
2
3
4
    // Pass lhs by value, modify it, and pass it thru.
    friend Complex operator+(Complex lhs, const Complex& rhs) {
        return lhs += rhs;
    }



Some questions:
1. Why is this operator overload declared as a "friend"?
2. When you say "pass it through" do you mean the result of the sum returns the lhs object (with rhs added) or does it return a new complex object?
You should definitely return a string instead of a char * from to_string(). Otherwise you leave the caller with the burden of deleting the returned buffer, which they will probably forget to do. If you want, you could still sprintf() it into a local buffer and then copy the buffer to a string.

1
2
3
char* c = new char[100];
if (img_part >= 0) sprintf_s(c, sizeof(c), "%ld+%ldi", (long)real_part, (long)img_part);
else sprintf_s(c, sizeof(c), "%ld %ldi", (long)real_part, (long)img_part);

C is a pointer, so sizeof(c) is the size of the pointer, not the size of the array that it points to. Also, sprintf_s is not standard C++. Use snprintf instead:

Since real_part and imginary_part are doubles, you should print them that way

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class complex {
...
string toString();
...
};

...
string
complex::toString()
{
    char c[100];
    if (img_part >= 0)
        snprintf(c, sizeof(c), "%g+%gi", real_part, img_part);
    else
        snprintf(c, sizeof(c), "%g%gi", real_part, img_part);
    return c;                   // creates a string from c and returns it.
}
Last edited on
You should really be returning const char* if you want to return a string constant, or better yet, use std::string. You'd only need C-style string constants if you are using some C library that requires it, and even then, you can simply convert a std::string to a C-string using the c_str() method.
Topic archived. No new replies allowed.