Overloaded >> Operator i n Rational Numbers class

I'm a fairly new learner of c++, trying to get my head around overloading the >> operator for an assignment on fractions and mixed numbers.

I have a class (Rational) which takes the attributes n_ and d_ (numerator and denominator).

I want to overload the >> operator so that a user can input a number in the form of a mixed number: c,n/d i.e 1,1/2 _or_ just a fraction n/d i.e. 1/2, add them together, and then spit out the answer as a fraction or mixed number.

The code for overloading the >> operator I have below works for mixed numbers (1,1/2 + 1,1/2 returns 3) but if I enter 1/2 + 1/2, 1,1/2 + 1/2 or 1/2 + 1,1/2, it doesn't return anything at all.

It seems like I'm missing something really obvious here, any help will be appreciated. The arithmetic operators and output operators I have working fine, but the input is driving me crazy.

Thanks in advance!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
std::istream& operator>>(std::istream& in, Rational& r) {

    int n, d, c;
    
    if (in >> c && in.peek() == ',' && in.ignore() && in >> n && in.peek() == '/' && in.ignore() && in >> d) {
        r = Rational(((c * d) + n), d);
        std::cout << "IF1" << std::endl;
        return in;
    } else if (in >> n && in.peek() == '/' && in.ignore() && in >> d) {
        r = Rational(n, d);
        std::cout << "IF2" << std::endl;
        return in;
    }
    
    std::cout << "R: " << r.n_ << " and " << r.d_ << std::endl;
    std::cout << "In: " << &in << std::endl;
    return in;
}
Last edited on
This seems to work:
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
// I'm a fairly new learner of c++, trying to get my head around overloading 
// the >> operator for an assignment on fractions and mixed numbers.
// I have a class (Rational) which takes the attributes n_ and d_ 
// (numerator and denominator).
// I want to overload the >> operator so that a user can input a number in the 
// form of a mixed number: c,n/d i.e 1,1/2 _or_ just a fraction n/d i.e. 1/2, 
// add them together, and then spit out the answer as a fraction or mixed number.
// The code for overloading the >> operator I have below works for mixed 
// numbers (1,1/2 + 1,1/2 returns 3) but if I enter 1/2 + 1/2, 1,1/2 + 1/2 or 
// 1/2 + 1,1/2, it doesn't return anything at all.
// It seems like I'm missing something really obvious here, any help will be 
// appreciated. The arithmetic operators and output operators I have working 
// fine, but the input is driving me crazy.
#include <iostream>
#include <limits>
#include <string>

class Rational {
public:
    int n  {}, // numerator
        d {1}; // denominator
    Rational addRationals(const Rational& other);
    Rational& operator+=(const Rational& other);
    friend std::istream& operator>>(std::istream& in, Rational& r);
    friend Rational operator+(Rational left, const Rational& right)
    {
        left += right;
        return left;
    }
    friend std::ostream& operator<<(std::ostream& os, const Rational& other);
private:
    void resolveInput(std::string& expr);
    void readRational(std::string expr);
};

Rational Rational::addRationals(const Rational& other)
{
    n = (n * other.d) + (d * other.n);
    d *= other.d;
    return *this;
}

Rational& Rational::operator+=(const Rational& other)
{
    addRationals(other);
    return *this;
}

void waitForEnter();

int main()
{
    Rational a;
    std::cout << "Please insert a sum of rationales: ";
    std::cin >> a;
    waitForEnter();
    return 0;
}

void Rational::resolveInput(std::string& expr)
{
    std::string::size_type pos = expr.find(',');
    if(std::string::npos == pos ) { // If no comma, then only a/b is possible
        readRational(expr);
        return;
    }
    readRational(expr.substr(0, pos)); // first chunk until comma
    expr.erase(0, ++pos); // comma included
    Rational r1;
    r1.readRational(expr);
    *this += r1;
}

void Rational::readRational(std::string expr)
{
    // expr can be:
    // a
    // a/b
    std::string::size_type pos = expr.find('/');
    if(std::string::npos == pos ) { // if no slash, then only numerator
        n = std::stoi(expr);
        return;
    }
    n = std::stoi(expr.substr(0, pos));
    expr.erase(0, ++pos);
    d = std::stoi(expr);
}

std::istream& operator>>(std::istream& in, Rational& r)
{
    std::string expr;
    in >> expr; // beware! Whitespaces break the code
    // expr can be any of the following:
    // a/b,c/d (means a/b + c/d)
    // a,b/c   (means a + b/c)
    // a/b,c   (means a/b + c)
    // a/b
    
    // I) read until '+'
    r.resolveInput(expr);
    
    // II) eat the '+'
    in >> expr;

    // III) read second expression
    Rational r1;
    in >> expr;
    r1.resolveInput(expr);
    r += r1;

    // IV) display the result
    std::cout << "Result: " << r << '\n';
    return in;
}

std::ostream& operator<<(std::ostream& os, const Rational& other)
{
    return os << other.n << '/' << other.d;
}

void waitForEnter()
{
    std::cout << "\nPress ENTER to continue...\n";
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}


You'd better provide a minimum compilable or nearly compilable example of code which reproduces your error in the future. Otherwise, you could get no help.
Last edited on
Topic archived. No new replies allowed.