// 'Rational' class interface: support operations for rational numbers
//
// ******************PUBLIC OPERATIONS*********************
// =, +=, -=, /=, *=      --> Assignment operators
// +, -, *, /             --> Binary arithmetic operators
// <, <=, >, >=, ==, !=   --> Relational and Equality
// << and >>              --> Input and Output (stream operators)
// double double_value( ) --> Return double equivalent

#include <iostream>

using namespace std;

#ifndef _RATIONAL
#define _RATIONAL

class Rational
{
    // Friend functions of the class, overloads the stream operators
    // "<<"  and  ">>"  for input and output.
    friend ostream& operator<<( ostream& Out, const Rational& Value );

    friend istream& operator>>( istream& In, Rational& Value );

  public:
// CONSTRUCTORS: with (a) no initializers or (b) an integer
//     that specifies the numerator, or (c) two integers
//     specifying numerator and denominator, or
//     (d) another Rational object
    Rational( const int &Numerator = 0 );
    //This is the default constructor(a) initializes object to zero(0)
    //and the integer initializing constructor(b), doing double duty

    Rational( const int &Numerator, const int &Denominator );
    //The two value initializing constructor, crashes if divisor value is 0

    Rational( const Rational &Rhs );  //Standard copy constructor

  // Assignment Operators
    const Rational& operator= ( const Rational &Rhs );

    const Rational& operator+=( const Rational &Rhs );

    const Rational& operator-=( const Rational &Rhs );

    const Rational& operator/=( const Rational &Rhs );

    const Rational& operator*=( const Rational &Rhs );


    // Mathematical Binary Operators, the calling object
    // is the left-hand side operand,
    Rational operator+( const Rational &Rhs ) const;

    Rational operator-( const Rational &Rhs ) const;

    Rational operator/( const Rational &Rhs ) const;

    Rational operator*( const Rational &Rhs ) const;


    // Relational and Equality Operators
    bool operator< ( const Rational &Rhs ) const;

    bool operator<=( const Rational &Rhs ) const;

    bool operator> ( const Rational &Rhs ) const;

    bool operator>=( const Rational &Rhs ) const;

    bool operator==( const Rational &Rhs ) const;

    bool operator!=( const Rational &Rhs ) const;


    // Unary Operators;  Prefix means   ++r  or  --r
    //                   Postfix means  r++  or  r--
    const Rational& operator++( );    // Prefix

    Rational operator++( int );        // Postfix

    const Rational& operator--( );    // Prefix

    Rational operator--( int );        // Postfix

    const Rational& operator+( ) const; //Unary + operator

    Rational operator-( ) const;    //Unary - operator

    bool operator!( ) const;


  // Member Function
    double double_value( ) const   // Do the division
        { return double( Numer ) / double( Denom ); }

//private:
    int        Numer;             // The numerator
    int        Denom;             // The denominator

    void FixSigns( );          // Ensures Denom > 0
    void Reduce( );            // Ensures reduced form

};

#endif

<--------------------------------------------------------------------------------->
#include "Rational.h"
#include<iostream>

using namespace std;

Rational::Rational( const int &Numerator )
{
    Numer = Numerator;
    Denom = 1;
}

Rational::Rational( const int &Numerator, const int &Denominator )
{
    Numer = Numerator;
    Denom = Denominator;
    FixSigns( );
    Reduce( );
}

Rational::Rational( const Rational &Rhs )
{
    Numer = Rhs.Numer;
    Denom = Rhs.Denom;
}

// N is guaranteed non-negative
int Gcd1( const int &N, const int &M )
{
    if( N % M == 0 )
        return M;
    else
        return Gcd1( M, N % M );
}

int Gcd( const int& M, const int &N )
{
    if( M > 0 )
        return Gcd1( N, M );
    else
        return Gcd1( N, -M );
}

void  Rational::FixSigns( )
{
    if( Denom < 0 )
    {
        Denom = -Denom;
        Numer = -Numer;
    }
}

void  Rational::Reduce( )
{
    int D = 1;

    if( Denom != 0 && Numer != 0 )
        D = Gcd( Numer, Denom );

    if( D > 1 )
    {
        Numer /= D;
        Denom /= D;
    }
}

const Rational &Rational::operator=( const Rational &Rhs )
{
    if( this != &Rhs )
    {
        Numer = Rhs.Numer;
        Denom = Rhs.Denom;
    }
    return *this;
}

const Rational &Rational::operator+=( const Rational &Rhs )
{
    Numer = Numer * Rhs.Denom + Rhs.Numer * Denom;
    Denom = Denom * Rhs.Denom;
    Reduce( );

    return *this;
}

const Rational &Rational::operator-=( const Rational &Rhs )
{
    Numer = Numer * Rhs.Denom - Rhs.Numer * Denom;
    Denom = Denom * Rhs.Denom;
    Reduce( );

    return *this;
}

const Rational & Rational::operator*=( const Rational &Rhs )
{
    int NewNumer = Numer * Rhs.Numer;
    int NewDenom = Denom * Rhs.Denom;

    Numer = NewNumer;        Denom = NewDenom;
    Reduce( );

    return *this;
}

const Rational &Rational::operator/=( const Rational &Rhs )
{
    int NewNumer = Numer * Rhs.Denom;
    int NewDenom = Denom * Rhs.Numer;

    Numer = NewNumer;        Denom = NewDenom;

    FixSigns( );            Reduce( );

    return *this;
}

Rational Rational::operator+( const Rational &Rhs ) const
{
    Rational Answer( *this );
    Answer += Rhs;
    return Answer;
}

Rational Rational::operator-( const Rational &Rhs ) const
{
    Rational Answer( *this );
    Answer -= Rhs;
    return Answer;
}

Rational Rational::operator*( const Rational &Rhs ) const
{
    Rational Answer( *this );
    Answer *= Rhs;
    return Answer;
}

Rational Rational::operator/( const Rational &Rhs ) const
{
    Rational Answer( *this );
    Answer /= Rhs;
    return Answer;
}

bool  Rational::operator==( const Rational &Rhs ) const
{
    return Numer * Rhs.Denom == Denom * Rhs.Numer;
}

bool Rational::operator!=( const Rational &Rhs ) const
{
    return Numer * Rhs.Denom != Denom * Rhs.Numer;
}
bool Rational::operator<=( const Rational &Rhs ) const
{
    return Numer * Rhs.Denom <= Denom * Rhs.Numer;
}

bool Rational::operator<( const Rational &Rhs ) const
{
    return Numer * Rhs.Denom < Denom * Rhs.Numer;
}

bool Rational::operator>=( const Rational &Rhs ) const
{
    return Numer * Rhs.Denom >= Denom * Rhs.Numer;
}

bool Rational::operator>( const Rational &Rhs ) const
{
    return Numer * Rhs.Denom > Denom * Rhs.Numer;
}

const Rational &Rational::operator++( )
{
    Numer += Denom;
    return *this;
}

Rational Rational::operator++( int )
{
    Rational Tmp = *this;
    Numer += Denom;
    return Tmp;
}

const Rational &Rational::operator--( )
{
    Numer -= Denom;
    return *this;
}

Rational Rational::operator--( int )
{
    Rational Tmp = *this;
    Numer -= Denom;
    return Tmp;
}

bool Rational::operator!( ) const
{
    return !Numer;
}

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

Rational Rational::operator-( ) const
{
    return Rational( -Numer, Denom );
}

istream& operator>>( istream& In, Rational& Value )
{
    // nn and dd are int values for the numerator and denominator, resp.
    //Input function expects   nn/dd   for rational object form
    // or  nn  only for a whole number(denominator will be set to 1)
    In >> Value.Numer;
    
    char Ch;
    In >> Ch;
    if( Ch == '/' )
    {
        In >> Value.Denom;
        Value.FixSigns( );
        Value.Reduce( );
    }
    else
    {
        Value.Denom = 1;
        In.putback( Ch );
    }
    return In;
}

ostream& operator<<( ostream& Out, const Rational& Value )
{
    if( Value.Denom != 0 )
    {
        Out << Value.Numer;
        if( Value.Denom != 1 )
            Out << '/' << Value.Denom;
        return Out;
    }
    if( Value.Numer == 0 )
        Out << "indeterminate";
    else
    {
        if( Value.Numer < 0 )
            Out << '-';
        Out << "infinity";
    }
    return Out;
}
<---------------------------------------------------------------------->

#include<iostream>
#include<fstream>
#include <cstdlib>
#include"Rational.h"

using namespace std;

void sort(int a[], int size)
{
    for (int i = 1; i < size; i++)
        for ( int j = 0; j < size - 1; j++)
        {
            if(a[j] > a [ j+ 1])
                swap ( a [j], a[ j+ 1]);
        }
}

int main()
{
    Rational list[150];

    ifstream fin;
    ofstream fout;
   
    int m, n, k=0;
   
    char ifile[25];
    cout <<"Please enter the name of the file for input(input.dat): ";
    cin >> ifile;
    //fin.open (ifile, ios::nocreate);
    if(fin.fail ())
    {
        cout <<"Input file failed to open."<<endl;
        exit(1);
    } 

    char ofile[25];

    cout<<"Please enter the name of output file(out.dat): ";
    cin >>ofile;
    fout.open (ofile);
    if (fout.fail ())
    {
        cout << "Output file failed to open."<<endl;
        exit(1);
    } 

    //fin>>r1;
    //fin>>r2;

    for(m=17; m<30;m++)
        for(n=5; n<23; n = n+2)
        {
            Rational temp(m,n);
            list[k] = temp;
            k++;
        }

        ofstream outfil("out.dat");
        for(m=0; m<100; m++)
        {
            outfil << list[m] << '\t';
            if(m % 5 == 4)
                outfil << endl;
            //echo output to screen
            fout<<list[m] << '\t';
            if(m % 5==4)
                fout<< endl;
        }
        outfil << endl;
        //sort(int a[], int size);
        fout<<endl;
        return 0;
}
<------------------------------------------------------------>
input
17/5    17/7    17/9    17/11   17/13
17/15   1       17/19   17/21   18/5
18/7    2       18/11   18/13   6/5
18/17   18/19   6/7     19/5    19/7
19/9    19/11   19/13   19/15   19/17
1       19/21   4       20/7    20/9
20/11   20/13   4/3     20/17   20/19
20/21   21/5    3       7/3     21/11
21/13   7/5     21/17   21/19   1
22/5    22/7    22/9    2       22/13
22/15   22/17   22/19   22/21   23/5
23/7    23/9    23/11   23/13   23/15
23/17   23/19   23/21   24/5    24/7
8/3     24/11   24/13   8/5     24/17
24/19   8/7     5       25/7    25/9
25/11   25/13   5/3     25/17   25/19
25/21   26/5    26/7    26/9    26/11
2       26/15   26/17   26/19   26/21
27/5    27/7    3       27/11   27/13
9/5     27/17   27/19   9/7     28/5
<--------------------------------------------------->
output
17/5    17/7    17/9    17/11    17/13   
17/15    1    17/19    17/21    18/5   
18/7    2    18/11    18/13    6/5   
18/17    18/19    6/7    19/5    19/7   
19/9    19/11    19/13    19/15    19/17   
1    19/21    4    20/7    20/9   
20/11    20/13    4/3    20/17    20/19   
20/21    21/5    3    7/3    21/11   
21/13    7/5    21/17    21/19    1   
22/5    22/7    22/9    2    22/13   
22/15    22/17    22/19    22/21    23/5   
23/7    23/9    23/11    23/13    23/15   
23/17    23/19    23/21    24/5    24/7   
8/3    24/11    24/13    8/5    24/17   
24/19    8/7    5    25/7    25/9   
25/11    25/13    5/3    25/17    25/19   
25/21    26/5    26/7    26/9    26/11   
2    26/15    26/17    26/19    26/21   
27/5    27/7    3    27/11    27/13   
9/5    27/17    27/19    9/7    28/5