/* June 30, 1998 */
/* Case Study: Arithmetic with Common Fractions */
/* Program that can add, subtract, multiply, divide two fractions input 
by the user */

#include 
#include  /* provides fucntion abs */

/* Function Prototypes */
void scan_fraction (int *nump, int *denomp);
char get_operator(void);
void add_fractions (int n1, int d1, int n2, int d2, int *n_ansp, int 
*d_ansp);
void multiply_fractions (int n1, int d1, int n2, int d2, int *n_ansp, int 
*d_ansp);
int find_gcd (int n1, int n2);
void reduce_fraction (int *nump, int *denomp);
void print_fraction (int num, int denom);

main ()
{
	int n1, d1;
	int n2, d2;
	char op;
	char again;
	int n_ans, d_ans;

	/* Get Input */
	do {
		/* Get a fraction problem */
		scan_fraction (&n1, &d1);
		op = get_operator();
		scan_fraction (&n2, &d2);

		/* Computes the result */
		switch (op) {
		case '+':
			add_fractions (n1, d1, n2, d2, &n_ans, &d_ans);
			break;
		case '-':
			add_fractions (n1, d1, -n2, d2, &n_ans, &d_ans);
			break;
		case '*':
			multiply_fractions (n1, d1, n2, d2, &n_ans, &d_ans);
			break;
		case '/':
			multiply_fractions (n1, d1, d2, n2, &n_ans, &d_ans);
		}
		reduce_fraction(&n_ans, &d_ans);

		/* Displays problem and result */
		printf ("\n");
		print_fraction (n1, d1);
		printf (" %c ", op);
		print_fraction (n2, d2);
		printf (" = ");
		print_fraction(n_ans, d_ans);

		/* Asks user about doing another problem */
		printf ("\nDo another problem? (y/n)> ");
		scanf (" %c", &again);
	} while (again == 'y' || again == 'Y');
}


/* Gets and returns a valid fraction as its result */
void scan_fraction (int *nump, int *denomp)
{
	char slash;
	int status;
	int error;
	char discard;

	do {
		/* No errors detected yet */
		error = 0;

		/* Get a fraction from the user */
		printf ("Enter a common fraction as two integers ");
		printf ("separated by a slash> ");
		status = scanf ("%d %c%d", nump, &slash, denomp);

		/* Validate the function */
		if (status < 3) {
			error = 1;
			printf ("Invalid-please read directions carefully\n");
		} else if (slash != '/') {
			error = 1;
			printf ("Invalid-separate numerator and denominator");
			printf (" by a slash (/)\n");
		} else if (*denomp <= 0) {
			error = 1;
			printf ("Invalid-denominator must be positive\n");
		}
		/* Discard extra input characters */
		do {
			scanf ("%c", &discard);
		} while (discard != '\n');
	} while (error);
}

/* Gets and returns a valid arithmetic operator. Skips over newline 
characters and permits re-entry of operator in case of error. */
char
get_operator(void)
{
	char op;

	printf("Enter an arithmetic operator (+,-,* or /)\n> ");
	for (scanf("%c", &op);
		op != '+' && op != '-' &&
		op != '*' && op != '/';
	scanf("%c", &op)) {
	if (op != '\n')
		printf("%c invalid, reenter operator (+,-,*,/)\n> ", op);
	}
	return (op);
}


/* Adds fractions from the input values */
void add_fractions (int n1, int d1, int n2, int d2, int *n_ansp, int *d_ansp)
{
	int denom, numer, sign_factor;

	/* Finds a common deminator */
	denom = d1 * d2;

	/* Computes numerator */
	numer = n1 * d2 + n2 * d1;

	/* Adjusts sign (at most, numerator should be negative) */
	if (numer * denom >= 0)
		sign_factor = 1;
	else
		sign_factor = -1;

	numer = sign_factor * abs(numer);
	denom = abs(denom);

	/* Returns result */
	*n_ansp = numer;
	*d_ansp = denom;
}

/* multip[ly fractions represented by pairs of integers */
void
multiply_fractions(int n1, int d1, int n2, int d2, int *n_ansp, int *d_ansp)
{
	/* local variables */
	int numer, denom;


	/* Computes numerator */
	numer = n1 * n2;

	/* Computes denominator */
	denom = d1 * d2;

        /* Display trace message */
        printf("\nEnter multiply_fractions with\n");
        printf("n1 = %d, d1 = %d, n2 = %d, d2 = %d\n", n1, d1, n2, d2);


	/* Returns result */
	*n_ansp = numer;
	*d_ansp = denom;
}



/* Finds greatest common divisor of two integers */
int find_gcd (int n1, int n2)
{
	int p, q, r, gcd;

	q = abs(n1);
	p = abs(n2);
	r = q%p;

	while (r != 0) {
		q = p;
		p = r;
		r = q%p;
	}
	gcd = p;

	/* Displays trace message */
	printf ("\nEntering find_gcd with n1 = %d, n2 = %d\n", n1, n2);

	/* Display exit trace message */
	printf ("The greatest common denominator is %d\n", gcd);
	return (gcd);
}
/* Reduces a fraction by dividing its numerator and denominator by their 
greatest common divider */
void reduce_fraction (int *nump, int *denomp)
{
	int gcd;

	gcd = find_gcd (*nump, *denomp);
	*nump = *nump / gcd;
	*denomp = *denomp / gcd;
}
/* Displays pair of integers as a fraction */
void print_fraction (int num, int denom)
{
	printf ("%d/%d", num, denom);
}


    Source: geocities.com/fire_168