CSCI-15 Assignment #4, operator functions/methods. 25 points. Due 11/6/2013

Extend your class MixedExpression class to include operator methods for addition, subtraction, multiplication and division, and to have friend operator << and operator >> functions for reading and printing the MixedExpression objects. Allow cascaded input and output per the << and >> operators in the standard I/O routines. Do not change your original add(), etc., methods, just add the new functionality.

Write a new version of the calculator to loop reading MixedExpression objects and operators and performing the indicated operations. Read and print the input and output using the same << and >> notation as if you were writing a calculator for integers.
If you did the original MixedExpression class and calculator correctly, this will be easy.

Here is my header file (MixedExpression.h):

#ifndef MIXEDEXPRESSION_H
#define MIXEDEXPRESSION_H
#include<fstream>
using namespace std;

class MixedExpression
{
    private:
        long a, b, c; // Variables of the mixed expression.
         // Reduce a mixed expression to its normal form.
        void reduce(void);
    public:
        MixedExpression(); // Default constructor.
        MixedExpression(long, long, long); // Normal constructor.
         // Add two mixed expressions.
        MixedExpression add(MixedExpression op);
         // Subtract two mixed expressions.
        MixedExpression subtract(MixedExpression op);
         // Multiply two mixed expressions.
        MixedExpression multiply(MixedExpression op);
         // Divide two mixed expressions.
        MixedExpression divide(MixedExpression op);
        void ReadMixedExp(istream &in); // Read each line.
        void printData(ostream &out); // Print the result.
        MixedExpression operator + (MixedExpression op);
        MixedExpression operator - (MixedExpression op);
        MixedExpression operator * (MixedExpression op);
        MixedExpression operator / (MixedExpression op);
    friend istream &operator >> (istream &, MixedExpression &);
    friend ostream &operator << (ostream &, MixedExpression &);
};
#endif

Here is my library source file (MixedExpression.cpp):

#include "MixedExpression.h"
#include<iostream>
#include<fstream>
using namespace std;

// Convert a mixed expression to its normal form.
void MixedExpression::reduce(void)
{
    long numerator = a*c + b; // Holds the numerator.
    long remainder = numerator % c; // Holds the remainder.
    long dividend = numerator / c; // Holds the dividend.
    long gcd = 1; // Holds the greatest common divisor.

    // Get the greatest common divisor.
    for (int i = 2; i <= remainder; i++)
    {
        if((c % i == 0) && (remainder % i == 0))
        {
            gcd = i;
        }
    }
    remainder /= gcd; // Divide the remainder by the GCD.
    c /= gcd; // Divide the denominator (c = denominator) by the GCD.
    a = dividend; // Set a equal to the dividend.
    b = remainder; // Set b equal to the remainder.
    if(b == 0) // If b is zero, set to default.
    {
        c = 1;
    }
}

// Set the first two values in the default constructor to 0
// and the third value to 1.
MixedExpression::MixedExpression()
{
    a = 0;
    b = 0;
    c = 1;
}

// Set three values in the normal constructor equal to the arguments.
MixedExpression::MixedExpression(long d, long e, long f)
{
    a = d;
    b = e;
    c = f;
}

// Add two mixed expressions and return the result.
MixedExpression MixedExpression::add(MixedExpression op)
{
    MixedExpression res;
    res.a = a + op.a;
    res.b = (b * op.c) + (op.b * c);
    res.c = c * op.c;
    return MixedExpression(res.a,res.b,res.c);
}

// Subtract two mixed expressions and return the result.
MixedExpression MixedExpression::subtract(MixedExpression op)
{
    MixedExpression res;
    res.a = a - op.a;
    res.b = (b * op.c) - (op.b * c);
    res.c = c * op.c;
    return MixedExpression(res.a,res.b,res.c);
}

// Multiply two mixed expressions and return the result.
MixedExpression MixedExpression::multiply(MixedExpression op)
{
    long numerator;
    long denominator;
    long remainder;
    MixedExpression res;

    numerator = (a*c + b) * (op.a * op.c + op.b);
    denominator = c * op.c;
    remainder = numerator % denominator;
    res.a = numerator/denominator;
    return MixedExpression(res.a,remainder,denominator);
}

// Divide two mixed expressions and return the result.
MixedExpression MixedExpression::divide(MixedExpression op)
{
    long numerator;
    long denominator;
    long remainder;
    MixedExpression res;

    numerator = (a*c + b) * (op.c);
    denominator = c * (op.a * op.c + op.b);
    remainder = numerator % denominator;
    res.a = numerator/denominator;
    return MixedExpression(res.a,remainder,denominator);
}

// Read each value and character.
void MixedExpression::ReadMixedExp(istream &in)
{
    char remove;
    in >> remove >> a >> remove >> b >> remove >> c >> remove;
}

// Print the results.
void MixedExpression::printData(ostream &out)
{
    reduce();
    out << "( " << a << " + " << b << " / " << c << " )";
}

MixedExpression MixedExpression::operator + (MixedExpression op)
{
    add(op);
}

MixedExpression MixedExpression::operator - (MixedExpression op)
{
    subtract(op);
}

MixedExpression MixedExpression::operator * (MixedExpression op)
{
    multiply(op);
}

MixedExpression MixedExpression::operator / (MixedExpression op)
{
    divide(op);
}

istream &operator >> (istream &in, MixedExpression &op)
{
    op.ReadMixedExp(in);
}

ostream &operator << (ostream &out, MixedExpression &op)
{
    op.printData(out);
}

Here is my calculator client file (Calculator.cpp):

#include "MixedExpression.h"
#include<iostream>
#include<fstream>
using namespace std;

int main(int argc, char *argv[])
{
    MixedExpression res;
    MixedExpression op1;
    MixedExpression op2; 
    char symbol;
    ifstream in;
    ofstream out;

    if(argc != 3)
    {
        cout << "Usage: program input-file output-file" << endl;
        return 1; // Return error code.
    }
    in.open(argv[1]); // Open input file on command line.
    out.open(argv[2]); // Open output file on command line.
    if(!in || !out) // Check if the files opened successfully.
    {
        cout << "There was an error opening the files!" << endl;
        return 1;
    }
    while(!in.eof())
    { 
        in >> op1 >> symbol >> op2;
        switch(symbol)
        {
            case '+': res = op1 + op2;
                break;
            case '-': res = op1 - op2;
                break;
            case '*': res = op1 * op2;
                break;
            case '/': res = op1 / op2;
                break;
        }
        out << op1 << " " << symbol << " " << op2 << " = " << res << endl;
    }
    // Close the input file.
    in.close();
    // Close the output file.
    out.close();
    return 0;
}

Here are my input lines:

( 1 + 2 / 6 ) + ( 3 + -3 / 9 )
( 3 + 5 / 9 ) + ( 2 + 3 / 7 )
( 0 + 0 / 1 ) + ( 1 + 0 / 1 )
( 7 + -3 / 9 ) - ( 3 + 7 / 8 )
( 3 + 2 / 5 ) - ( 1 + 4 / 7 )
( 1 + 0 / 1 ) - ( 0 + 0 / 1 )
( 7 + 5 / 25 ) * ( 4 + -6 / 14 )
( 3 + 1 / 4 ) * ( 1 + 2 / 6 )
( 1 + 0 / 1 ) * ( 0 + 0 / 1 )
( 4 + 4 / 5 ) / ( 2 + 3 / 6 )
( 8 + 3 / 4 ) / ( 2 + 1 / 3 )
( 0 + 0 / 1 ) / ( 1 + 0 / 1 )

The expected output I am trying to get is this:

( 1 + 1 / 3 ) + ( 2 + 2 / 3 ) = ( 4 + 0 / 1 )
( 3 + 5 / 9 ) + ( 2 + 3 / 7 ) = ( 5 + 62 / 63 )
( 0 + 0 / 1 ) + ( 1 + 0 / 1 ) = ( 1 + 0 / 1 )
( 6 + 2 / 3 ) - ( 3 + 7 / 8 ) = ( 2 + 19 / 24 )
( 3 + 2 / 5 ) - ( 1 + 4 / 7 ) = ( 1 + 29 / 35 )
( 1 + 0 / 1 ) - ( 0 + 0 / 1 ) = ( 1 + 0 / 1 )
( 7 + 1 / 5 ) * ( 3 + 4 / 7 ) = ( 25 + 5 / 7 )
( 3 + 1 / 4 ) * ( 1 + 1 / 3 ) = ( 4 + 1 / 3 )
( 1 + 0 / 1 ) * ( 0 + 0 / 1 ) = ( 0 + 0 / 1 )
( 4 + 4 / 5 ) / ( 2 + 1 / 2 ) = ( 1 + 23 / 25 )
( 8 + 3 / 4 ) / ( 2 + 1 / 3 ) = ( 3 + 3 / 4 )
( 0 + 0 / 1 ) / ( 1 + 0 / 1 ) = ( 0 + 0 / 1 )
( 0 + 0 / 1 ) / ( 1 + 0 / 1 ) = ( 0 + 0 / 1 )

Now all I am getting is this:

( 1 + 1 / 3 ) + ( 2 + 2 / 3 ) = ( -94 + -446902 / 2293064 )
( 3 + 5 / 9 ) + ( 2 + 3 / 7 ) = ( -94 + -446902 / 2293064 )
( 0 + 0 / 1 ) + ( 1 + 0 / 1 ) = ( -94 + -446902 / 2293064 )
( 6 + 2 / 3 ) - ( 3 + 7 / 8 ) = ( -94 + -446902 / 2293064 )
( 3 + 2 / 5 ) - ( 1 + 4 / 7 ) = ( -94 + -446902 / 2293064 )
( 1 + 0 / 1 ) - ( 0 + 0 / 1 ) = ( -94 + -446902 / 2293064 )
( 7 + 1 / 5 ) * ( 3 + 4 / 7 ) = ( -94 + -446902 / 2293064 )
( 3 + 1 / 4 ) * ( 1 + 1 / 3 ) = ( -94 + -446902 / 2293064 )
( 1 + 0 / 1 ) * ( 0 + 0 / 1 ) = ( -94 + -446902 / 2293064 )
( 4 + 4 / 5 ) / ( 2 + 1 / 2 ) = ( -94 + -446902 / 2293064 )
( 8 + 3 / 4 ) / ( 2 + 1 / 3 ) = ( -94 + -446902 / 2293064 )
( 0 + 0 / 1 ) / ( 1 + 0 / 1 ) = ( -94 + -446902 / 2293064 )
( 0 + 0 / 1 ) / ( 1 + 0 / 1 ) = ( -94 + -446902 / 2293064 )

I think the calculations are not coming out correct because in the overloading operator methods, I am not calling the add(), subtract(), multiply(), and divide() methods correctly. How can I call them correctly in the operator methods in order to get the correct output?

The return value of each of those functions may be incorrect. All they have to do is return res, they don't have to create another object

MixedExpression MixedExpression::add(MixedExpression op)
{
    MixedExpression res;
    res.a = a + op.a;
    res.b = (b * op.c) + (op.b * c);
    res.c = c * op.c;
    return res; // <<<<<<<<<<<<<<<<<<
}
This question has already been answered. Start a new discussion instead.