Member Avatar for andrew.mendonca.967

CSCI 15 Assignment #3, introduction to classes/objects. 100 points, due 10/21/13

A mixed expression is an expression of the form a + b/c, where a, b, and c are integers, b >= 0 and c > 0. By convention, b/c is always non-negative, and has the property that 0 <= (b/c) < 1. Also, b/c is always shown in reduced form, or as 0 / 1.

Implement the MixedExpression class, allowing use of the mixed expression as an abstract data type. Also, write a calculator client to drive the MixedExpression class. Your MixedExpression class must be described in a header file (mixedexpression.h) and implemented in a separate library source file (mixedexpression.cpp), both of which are in the same working directory as the client calculator program. The client code will #include the header you wrote, and will be linked with the class library object file. Create a project for the 2 source files.

Your MixedExpression class must provide public member functions (methods) to add, subtract, multiply and divide mixed expressions. These must have the form:

MixedExpression MixedExpression::add( MixedExpression op )

This will add "this" mixed expression (e.g., "self" – the addend) to the argument op , the augend (remember, addend + augend yields sum) and return the sum. The other methods; subtract(), multiply(), and divide(), will also take a mixed expression (the argument) and treat it as the right hand operand of their appropriate operation, using self (the object to the left of the '.') as the left hand side operand. All of these functions will create a new MixedExpression, set its values, and return it so it can be assigned to the variable holding the result.

Given MixedExpression variables res, op1 and op2, the call in the calculator code will look like this:

res = op1.add( op2 );

You must also provide appropriate constructors, observers (i.e., to print a mixed expression, in the form (a + b / c), where parentheses and spaces are required), and manipulators (i.e., to take supplied values and set them into the mixed expression).

Your class data members (long a, b and c) must be private.

YOU MAY NOT ADD ANY OTHER DATA MEMBERS TO THE CLASS.

YOU MAY NOT ADD ANY OTHER PARAMETERS TO THE METHODS.

You may need private "helper" functions, for example, a private method reduce() to convert a mixed expression to its "normal" form.

Your program will read lines of text in the form
( a + b / c ) <operator> ( d + e / f )

where the parentheses ( ), the +, and the / are literals, <operator>  {+, -, *, /}, and a, b, c, d, e and f are signed integers.

Your input method, ReadMixedExp( istream &in ) is a method of the class MixedExpression, and extract the object's data values from input. Your client will call this twice per line of input, once for each operand. The parameter type istream & means the method can take either an istream or an ifstream as an argument.

Your client must extract the operator itself (a mixed expression doesn't understand math) between extracting the operands. The client must interpret the operator itself.

You may assume the input is correctly formatted. Use an input file and process one line at a time until you reach end-of-file. Output is to a text file. Pass the file names into the program via the command line. Print the entered line (converted to reduced normal form if needed), followed by =, then the result.

The operands and the result must print themselves. That is, you must use a method printData( ostream &out ) {which can take either an ostream or an ofstream} to print the mixed expression.

For example, with this input line

( 1 + 2 / 6 ) + ( 3 + -3 / 9 )

The corresponding output would be (notice changes from the input form to reduced normal form)

( 1 + 1 / 3 ) + ( 2 + 2 / 3 ) = ( 4 + 0 / 1 )

This spacing and format of the input and output lines is required.

Test your program with several sets of data, including attempts at illegal data or operations, such as
( 1+ 0/1 ) / ( 0 + 0/1 )

Your program must catch and appropriately handle undefined expressions such as 1+1/0. Just use the value 0+0/1 in these cases. Later, we'll see how to really handle these errors.

Here is my source code for the 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.
        long GCD(long x, long y) // Get the greatest common divisor.
        {
            long remainder; // Holds the remainder.
            while(y != 0)
            {
                // Get the value of the remainder by dividing y by x.
                remainder = x % y;
                x = y;
                y = remainder;
            }
            // Return the greatest common divisor.
            return x; 
        }
        // Convert a mixed expression to its normal form.
        void reduce(void)
        {
            long x, y;
            long gcd = GCD(x,y);
            x /= gcd;
            y /= gcd;
        }
    public:
        MixedExpression(); // Default constructor of the mixed expression class.
        MixedExpression(long, long, long);
        MixedExpression add(MixedExpression op); // Add two numbers.
        MixedExpression subtract(MixedExpression op); // Subtract two numbers.
        MixedExpression multiply(MixedExpression op); // Multiply two numbers.
        MixedExpression divide(MixedExpression op); // Divide two numbers.
        MixedExpression ReadMixedExp(istream &in); // Read each line.
        MixedExpression printData(ostream &out); // Print the result.
};
#endif

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

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

// Set three values in the default constructor to 0.
MixedExpression::MixedExpression()
{
    a = 0;
    b = 0;
    c = 1;
}

MixedExpression::MixedExpression(long a, long b, long c)
{
    a = a;
    b = b;
    c = c;
}

// Add two values and return the sum.
MixedExpression MixedExpression::add(MixedExpression op)
{
    MixedExpression res;
    res.a = (*this).a + op.b;
    return res;
}

// Subtract two values and return the difference.
MixedExpression MixedExpression::subtract(MixedExpression op)
{
    MixedExpression res;
    res.a = (*this).a - op.b;
    return res;
}

// Multiply two values and return the product.
MixedExpression MixedExpression::multiply(MixedExpression op)
{
    MixedExpression res;
    res.a = (*this).a * op.b;
    return res;
}

// Divide two values and return the quotient.
MixedExpression MixedExpression::divide(MixedExpression op)
{
    MixedExpression res;
    res.a = (*this).a / op.b;
    return res;
}

// Read each value while not at the end of the file.
MixedExpression MixedExpression::ReadMixedExp(istream &in)
{
    while(!in.eof())
    {
        in >> a >> b >> c;
    }
}

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

Here is my source code for the calculator client file:

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

int main(int argc, char *argv[])
{
    MixedExpression res;
    MixedExpression op1;
    MixedExpression op2;
    int num;
    ifstream in;
    ofstream out;
    char input[12] = "numbers.txt";
    char output[15] = "num result.txt";

    // Prompt for the file name.
    cout << "Enter the file name: ";
    cin >> input;

    // Open the input file.
    in.open(input);
    // Open the output file.
    out.open(output);

    if(in)
    {
        while(!in.eof())
        {
            res.ReadMixedExp(in)
            switch(num)
            {
                case 1: res = op1.add(op2); // Get the sum.
                    break;
                case 2: res = op1.subtract(op2); // Get the difference.
                    break;
                case 3: res = op1.multiply(op2); // Get the product.
                    break;
                case 4: res = op1.divide(op2); // Get the quotient.
                    break;
            }
        }
    }
    // Print the result.
    res.printData(out);
    // Close the input file.
    in.close();
    // Close the output file.
    out.close();

    return 0;
}

My problem is: With this input line, which is ( 1 + 2 / 6 ) + ( 3 + -3 / 9 ), I can't seem to get this output, which is ( 1 + 1 / 3 ) + ( 2 + 2 / 3 ) = ( 4 + 0 / 1 ). I don't understand what am I doing wrong. Is there anything I need to change in any of my three files to get the expected output?

You need to re-think your approach a little. you're trying to read the file directly without ignoring the extra stuff in there, like ()+/.

For instance here's the ReadMixedExp method redone to get the values in the object:

void MixedExpression::ReadMixedExp(istream &in)
{
    // ( 1 + 2 / 6 ) + ( 3 + -3 / 9 )
    //This read from 2 position before the first number.
    //in.ignore(5); before you call this for the second set
    //will put the position in the right place for the next read.
    in.ignore(2);   
    in >> a;
    in.ignore(3);
    in >> b;
    in.ignore(3);
    in >> c;
}

after the first read a=1,b=2,c=6

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.