#include <iostream>
#include <string>
#include <stdlib.h>
#include <cstring>

using namespace std;

class Fraction
{
    private:
        int num, den;       // numerator & demoninator
    public:
        Fraction() { set(0, 1); }
        Fraction(int n, int d) { set(n, d); }
        void set(int n, int d) { num = n; den = d; normalize(); }
        int get_num() { return num; }
        int get_den() { return den; }
        Fraction add(Fraction other);
        Fraction mult(Fraction other);
        Fraction(Fraction const &src);
        Fraction(char* s);
    private:
        void normalize();               // convert to standard form
        int gcf(int a, int b);          // greatest common factor
        int lcm(int a, int b);          // lowest common denominatro
};

int main()
{
    Fraction f1(3, 4);
    Fraction f2(f1);
    Fraction f3 = f1.add(f2);

    cout << "The value of f3 is ";
    cout << f3.get_num() << "/";
    cout << f3.get_den() << endl;

    Fraction a = "1/2", b = "1/3";
    //Fraction arr_of_fract[4] = {"1/2", "1/3", "3/4"};

    cout << "The value of a is ";
    cout << a.get_num() << "/";
    cout << a.get_den() << endl;

    return 0;
}

Fraction::Fraction(char* s)
{
    int n = 0;
    int d = 1;
    char *p1 = strtok(s, "/, ");
    char *p2 = strtok(NULL, "/, ");

    if(p1 != NULL)
        n = atoi(p1);
    if(p2 != NULL)
        d = atoi(p2);
    set(n, d);
}

Fraction::Fraction(Fraction const &src)
{
    cout << "Now calling copy constructor." << endl;
    num = src.num;
    den = src.den;
}

void Fraction::normalize()
{
    // handle cases involving 0

    if(den == 0 || num == 0)
    {
        num = 0;
        den = 1;
    }

    // put neg, sign in numerator only

    if(den < 0)
    {
        num *= -1;
        den *= -1;
    }

    // factor out GCF from numerator and denominator

    int n = gcf(num, den);
    num = num / n;
    den = den / n;
}

int Fraction::gcf(int a, int b)
{
    if(b == 0)
        return abs(a);
    else
        return gcf(b, a%b);
}

int Fraction::lcm(int a, int b)
{
    int n = gcf(a, b);
    return a / n * b;
}

Fraction Fraction::add(Fraction other)
{
    Fraction fract;
    int lcd = lcm(den, other.den);
    int quot1 = lcd / den;
    int quot2 = lcd / other.den;
    fract.set(num * quot1 + other.num * quot2, lcd);

    return fract;
}

Fraction Fraction::mult(Fraction other)
{
    Fraction fract;
    fract.set(num * other.num, den * other.den);

    return fract;
}

In the code above I'm having trouble understanding most every line in the c-string constructor, Fraction(char* s)
Could someone give me a line by line explanation please? Thanks.

It's simple, first, you initialize the values with 0 and 1 to have valid input in case strok fails. Then you call strtok to parse the input that you get from the constructor as a char pointer. Strok is a function that splits C - string based on a delimiter(also a C - string) that you want, in this case the "/" because fractions are represented in the form "x/y". The function strok is called twice because strtok returns every time you call it a token from the split operation. So if you would have splitted "2/3/4" you would call strtok 3 times, first you get 2, then 3 and then 4. In your case you need to call it twice, to get the numerator and denominator. The rest is self - explainig, if the parsing is successful you get the new values else use default

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.