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');
}
|