Operator>> Overloading
c++, operator-overloading
Solution
Essentially your `operator >>` is way too complex, and doesn’t even handle errors properly. You shouldn’t read the value into a string to begin with – read it directly into a number. Furthermore, after each read operation you need to check (and potentially set) the stream’s state.
istream& operator >>(istream& in, ComplexNumber& value) {
int re;
if (not (in >> re)) {
return in;
char pm;
if (not (in >> pm) or (pm != '+' and pm != '-') {
in.setstate(ios::failbit);
return in;
}
int im;
if (not (in >> im))
return in;
char i;
if (not (in >> i) or i != 'i') {
in.setstate(ios::failbit);
return in;
}
value = ComplexNumber {re, (pm == '-' ? -im : im)};
return in;
}
(I used C++11 initialisers because I’m lazy ….)
And, yes, this can be written even shorter by pulling the whole reading into a single chainged expression:
istream& operator >>(istream& in, ComplexNumber& value) {
int re;
int im;
char pm;
char i;
if (not (in >> re >> pm) or
(pm != '+' and pm != '-') or
not (in >> im >> i) or
i != 'i')
{
in.setstate(ios::failbit);
return in;
}
value = ComplexNumber {re, (pm == '-' ? -im : im)};
return in;
}
Whether this is better depends on the audience. Personally, I do find it more (!) readable than the first version. A more structured alternative (which would be overkill for such a simple case) is Boost.Qi which allows very elegant parser construction.
Problem
I am implementing a complex number using operator overloading. In the program, the user enters a complex number ALWAYS in the form: ``` a + bi ``` So, in example... ``` 25.0 + 3.6i ``` Assume that the user will always enter both the real and the imaginary parts of the complex number, e.g., the user will enter "5 + 0i" (and not "5") or "0 - 6.2i" (and not "-6.2i"). My problem is that in main() I have the following code: ``` ComplexNumber c1; cin >> c1; cout << c1; ``` and the code prints: ``` 0 + 0i ``` ...when I entered "4.2 + 8.3i" into the prompt during runtime. Here is my implementation of my `operator>>` class: ``` istream & operator>>(istream & in, ComplexNumber & n) { string real; string imag; bool done = false; int sign = 1; string num; in >> num; int length; for (int i = 0; i < num.length(); i++) { if (num.at(i) == 'i') { imag = num.substr((i - length), i); } else if (num.at(i) == '-') { sign = -1; } else if (num.at(i) == ' ') { if (!done) { real = num.substr(i); done = true; } length = 0; } length++; } n = ComplexNumber(atof(real.c_str()), atof(imag.c_str()) * sign); return in; } ``` Here is my implementation of `operator<<` class: ``` ostream & operator<<(ostream & out, const ComplexNumber & n) { n.print(out); return out; } ``` Here is my implementation of the ComplexNumber member class print(): ``` void ComplexNumber::print(ostream & out) const { if (imag >= 0) out << real << " + " << imag << "i"; else out << real << " - " << (-1 * imag) << "i"; } ``` This is my ComplexNumber header file for further details: ``` #ifndef COMPLEXNUMBER_H #define COMPLEXNUMBER_H #include <iostream> using namespace std; class ComplexNumber { public: // constructors ComplexNumber(); ComplexNumber(double real_part, double imaginary_part); ComplexNumber(const ComplexNumber & rhs); // named member functions void print(ostream & out = cout) const; bool equals(const ComplexNumber & rhs) const; // assignment operators const ComplexNumber & operator=(const ComplexNumber & rhs); const ComplexNumber & operator+=(const ComplexNumber & rhs); const ComplexNumber & operator-=(const ComplexNumber & rhs); const ComplexNumber & operator*=(const ComplexNumber & rhs); private: double real; double imag; }; // arithmetic operators ComplexNumber operator+(const ComplexNumber & lhs, const ComplexNumber & rhs); ComplexNumber operator-(const ComplexNumber & lhs, const ComplexNumber & rhs); ComplexNumber operator*(const ComplexNumber & lhs, const ComplexNumber & rhs); // relational operators bool operator==(const ComplexNumber & lhs, const ComplexNumber & rhs); bool operator!=(const ComplexNumber & lhs, const ComplexNumber & rhs); // I/O operators ostream & operator<<(ostream & out, const ComplexNumber & n); istream & operator>>(istream & in, ComplexNumber & n); #endif ``` Any help with my implementations would be great.