Nov 13, 2019 at 2:18pm UTC
Hey, I feel like the solution to my problem is simple, but I've spent hours trying to find it and I think a new pair of eyes would help. I posted my client file and correct output in the comments. Sorry about how long it all is I just thought to include it all just in case and the client file isn't allowed to be edited btw. Any helps appreciated thank you.
fraction.h(first file)
#pragma once
#include <iostream>
using namespace std;
namespace cs_fraction {
class Fraction
{
public:
fraction
Fraction();
Fraction(int);
Fraction(int inNumerator, int inDenominator);
friend Fraction operator+(const Fraction& left, const Fraction& right);
friend Fraction operator-(const Fraction& left, const Fraction& right);
friend Fraction operator*(const Fraction& left, const Fraction& right);
friend Fraction operator/(const Fraction& left, const Fraction& right);
friend bool operator<(const Fraction& left, const Fraction& right);
friend bool operator>(const Fraction& left, const Fraction& right);
friend bool operator==(const Fraction& left, const Fraction& right);
friend bool operator!=(const Fraction& left, const Fraction& right);
friend bool operator<=(const Fraction& left, const Fraction& right);
friend bool operator>=(const Fraction& left, const Fraction& right);
Fraction operator+=(const Fraction& right);
Fraction operator-=(const Fraction& right);
Fraction operator*=(const Fraction& right);
Fraction operator/=(const Fraction& right);
Fraction operator++();
Fraction operator++(int k);
Fraction operator--();
Fraction operator--(int k);
friend ostream& operator<<(ostream& out, const Fraction& right);
friend istream& operator>>(istream& in, Fraction& read);
private:
int numerator;
int denominator;
void simplify();
};
}
fraction.cpp (second file)
#include <iostream>
#include "fraction.h"
#include <cassert>
using namespace std;
namespace cs_fraction {
Fraction::Fraction()
{
numerator = 0;
denominator = 1;
}
Fraction::Fraction(int num)
{
numerator = num;
denominator = 1;
}
Fraction::Fraction(int inNumerator = 0, int inDenominator = 1)
{
assert(inDenominator != 0);
numerator = inNumerator;
denominator = inDenominator;
simplify();
}
// Reducing the fraction to its smallest form
void Fraction::simplify()
{
int gcf;
gcf = numerator;
if (denominator < 0)
{
denominator = denominator * -1;
}
while ((numerator % gcf != 0) || (denominator % gcf != 0))
{
gcf--;
}
if (gcf > 0)
{
numerator /= gcf;
denominator /= gcf;
}
}
Fraction operator+(const Fraction& left, const Fraction& right)
{
Fraction answer(left.numerator * right.denominator + left.denominator * right.numerator, left.denominator * right.denominator);
answer.simplify();
return answer;
}
Fraction operator-(const Fraction& left, const Fraction& right)
{
return Fraction(left.numerator * right.denominator + left.denominator * right.numerator, left.denominator * right.denominator);
}
Fraction operator*(const Fraction& left, const Fraction& right)
{
return Fraction(left.numerator * right.numerator, left.denominator * right.denominator);
}
Fraction operator/(const Fraction& left, const Fraction& right)
{
return Fraction(left.numerator * right.denominator, left.denominator * right.numerator); }
bool operator<(const Fraction& left, const Fraction& right)
{
return (left.numerator * right.denominator) < (right.numerator * left.denominator);
}
bool operator>(const Fraction& left, const Fraction& right)
{
return (left.numerator * right.denominator) > (right.numerator * left.denominator);
}
bool operator==(const Fraction& left, const Fraction& right)
{
return (left.numerator * right.denominator) == (right.numerator * left.denominator);
}
bool operator!=(const Fraction& left, const Fraction& right)
{
return (left.numerator * right.denominator) != (right.numerator * left.denominator);
}
bool operator<=(const Fraction& left, const Fraction& right)
{
return (left.numerator * right.denominator) <= (right.numerator * left.denominator);
}
bool operator>=(const Fraction& left, const Fraction& right)
{ return (left.numerator * right.denominator) >= (right.numerator * left.denominator);
}
Fraction Fraction::operator+=(const Fraction& right)
{
*this = *this + right;
simplify();
return *this;
}
Fraction Fraction::operator-=(const Fraction& right)
{
*this = *this - right;
return *this;
}
Fraction Fraction::operator*=(const Fraction& right)
{
*this = *this * right;
return *this;
}
Fraction Fraction::operator/=(const Fraction& right)
{
*this = *this / right;
return *this;
}
Fraction Fraction::operator++()
{
numerator = numerator + denominator;
return *this;
}
Fraction Fraction::operator++(int k)
{
Fraction local(*this);
++(*this);
return local;
}
Fraction Fraction::operator--()
{
numerator = numerator - denominator;
return *this;
}
Fraction Fraction::operator--(int k)
{
Fraction temp(numerator, denominator);
numerator = numerator - denominator;
return temp;
}
ostream& operator<<(ostream& out, const Fraction& right)
{
if (right.denominator == 1)
{
out << right.numerator;
}
else if (abs(right.numerator) < right.denominator)
{
out << right.numerator << "/" << right.denominator;
}
else
{
out << right.numerator / right.denominator << "+" <<
(abs(right.numerator % right.denominator)) << "/" << right.denominator;
}
return out;
}
istream& operator>>(istream& in, Fraction& read)
{
int numerator, denominator, temp = 0;
in >> numerator;
char c;
in >> c;
if (c == '+')
{
in >> temp;
denominator = numerator;
numerator = temp;
temp = denominator;
in >> c;
}
if (c == '/')
{
in >> denominator;
}
else
{
in.putback(c);
denominator = 1;
}
numerator = (denominator * temp) + numerator;
read = Fraction(numerator, denominator);
return in;
}
}
Fraction.txt (text file)
# This file shows the patterns your Fraction class needs to be able to
# read. A Fraction may be just a single integer, two integers separated by
# a slash, or a mixed number which consists of an integer, followed by a +
# and then two integers with a slash. A minus sign may appear in the
# very first character to indicate the whole Fraction is negative.
# No white space is allowed in between the component parts of a Fraction.
#
1/3
3/6
3072/4096
-4/5
12/2
5
-8
21/15
-50/3
1+1/4
1+5/5
-4+3/12
-10+10/12
My output:
----- Testing basic Fraction creation & printing
(Fractions should be in reduced form, and as mixed numbers.)
Last edited on Nov 13, 2019 at 2:26pm UTC
Nov 13, 2019 at 2:22pm UTC
client.cpp(third file)
#include <iostream>
#include "fraction.h"
#include <fstream>
#include <cassert>
#include <string>
using namespace std;
using namespace cs_fraction;
void BasicTest();
void RelationTest();
void BinaryMathTest();
void MathAssignTest();
bool eof(ifstream& in);
string boolString(bool convertMe);
int main()
{
BasicTest();
RelationTest();
BinaryMathTest();
MathAssignTest();
}
void BasicTest()
{
cout << "\n----- Testing basic Fraction creation & printing\n";
cout << "(Fractions should be in reduced form, and as mixed numbers.)\n";
const Fraction fr[] = { Fraction(4, 8), Fraction(-15,21),
Fraction(10), Fraction(12, -3),
Fraction(), Fraction(28, 6), Fraction(0, 12) };
for (int i = 0; i < 7; i++) {
cout << "Fraction [" << i << "] = " << fr[i] << endl;
}
cout << "\n----- Now reading Fractions from file\n";
ifstream in("Fraction.txt");
assert(in);
while (!eof(in)) {
Fraction f;
if (in.peek() == '#') {
in.ignore(128, '\n'); //skip this line, it's a comment
}
else {
in >> f;
cout << "Read Fraction = " << f << endl;
}
}
}
bool eof(ifstream& in)
{
char ch;
in >> ch;
in.putback(ch);
return !in;
}
string boolString(bool convertMe) {
if (convertMe) {
return "true";
}
else {
return "false";
}
}
void RelationTest()
{
cout << "\n----- Testing relational operators between Fractions\n";
const Fraction fr[] = { Fraction(3, 6), Fraction(-15, 30), Fraction(1, 2),
Fraction(1,10), Fraction(0,1), Fraction(0,2) };
for (int i = 0; i < 5; i++) {
cout << "Comparing " << fr[i] << " to " << fr[i + 1] << endl;
cout << "\tIs left < right? " << boolString(fr[i] < fr[i + 1]) << endl;
cout << "\tIs left <= right? " << boolString(fr[i] <= fr[i + 1]) << endl;
cout << "\tIs left > right? " << boolString(fr[i] > fr[i + 1]) << endl;
cout << "\tIs left >= right? " << boolString(fr[i] >= fr[i + 1]) << endl;
cout << "\tDoes left == right? " << boolString(fr[i] == fr[i + 1]) << endl;
cout << "\tDoes left != right ? " << boolString(fr[i] != fr[i + 1]) << endl;
}
cout << "\n----- Testing relations between Fractions and integers\n";
Fraction f(-3, 6);
int num = 2;
cout << "Comparing " << f << " to " << num << endl;
cout << "\tIs left < right? " << boolString(f < num) << endl;
cout << "\tIs left <= right? " << boolString(f <= num) << endl;
cout << "\tIs left > right? " << boolString(f > num) << endl;
cout << "\tIs left >= right? " << boolString(f >= num) << endl;
cout << "\tDoes left == right? " << boolString(f == num) << endl;
cout << "\tDoes left != right ? " << boolString(f != num) << endl;
Fraction g(1, 4);
num = -3;
cout << "Comparing " << num << " to " << g << endl;
cout << "\tIs left < right? " << boolString(num < g) << endl;
cout << "\tIs left <= right? " << boolString(num <= g) << endl;
cout << "\tIs left > right? " << boolString(num > g) << endl;
cout << "\tIs left >= right? " << boolString(num >= g) << endl;
cout << "\tDoes left == right? " << boolString(num == g) << endl;
cout << "\tDoes left != right ? " << boolString(num != g) << endl;
}
void BinaryMathTest()
{
cout << "\n----- Testing binary arithmetic between Fractions\n";
const Fraction fr[] = { Fraction(1, 6), Fraction(1,3),
Fraction(-2,3), Fraction(5), Fraction(-4,3) };
for (int i = 0; i < 4; i++) {
cout << fr[i] << " + " << fr[i + 1] << " = " << fr[i] + fr[i + 1] << endl;
cout << fr[i] << " - " << fr[i + 1] << " = " << fr[i] - fr[i + 1] << endl;
cout << fr[i] << " * " << fr[i + 1] << " = " << fr[i] * fr[i + 1] << endl;
cout << fr[i] << " / " << fr[i + 1] << " = " << fr[i] / fr[i + 1] << endl;
}
cout << "\n----- Testing arithmetic between Fractions and integers\n";
Fraction f(-1, 2);
int num = 4;
cout << f << " + " << num << " = " << f + num << endl;
cout << f << " - " << num << " = " << f - num << endl;
cout << f << " * " << num << " = " << f * num << endl;
cout << f << " / " << num << " = " << f / num << endl;
Fraction g(-1, 2);
num = 3;
cout << num << " + " << g << " = " << num + g << endl;
cout << num << " - " << g << " = " << num - g << endl;
cout << num << " * " << g << " = " << num * g << endl;
cout << num << " / " << g << " = " << num / g << endl;
}
void MathAssignTest()
{
cout << "\n----- Testing shorthand arithmetic assignment on Fractions\n";
Fraction fr[] = { Fraction(1, 6), Fraction(4),
Fraction(-1,2), Fraction(5) };
for (int i = 0; i < 3; i++) {
cout << fr[i] << " += " << fr[i + 1] << " = ";
cout << (fr[i] += fr[i + 1]) << endl;
cout << fr[i] << " -= " << fr[i + 1] << " = ";
cout << (fr[i] -= fr[i + 1]) << endl;
cout << fr[i] << " *= " << fr[i + 1] << " = ";
cout << (fr[i] *= fr[i + 1]) << endl;
cout << fr[i] << " /= " << fr[i + 1] << " = ";
cout << (fr[i] /= fr[i + 1]) << endl;
}
cout << "\n----- Testing shorthand arithmetic assignment using integers\n";
Fraction f(-1, 3);
int num = 3;
cout << f << " += " << num << " = ";
cout << (f += num) << endl;
cout << f << " -= " << num << " = ";
cout << (f -= num) << endl;
cout << f << " *= " << num << " = ";
cout << (f *= num) << endl;
cout << f << " /= " << num << " = ";
cout << (f /= num) << endl;
cout << "\n----- Testing increment/decrement prefix and postfix\n";
Fraction g(-1, 3);
cout << "Now g = " << g << endl;
cout << "g++ = " << g++ << endl;
cout << "Now g = " << g << endl;
cout << "++g = " << ++g << endl;
cout << "Now g = " << g << endl;
cout << "g-- = " << g-- << endl;
cout << "Now g = " << g << endl;
cout << "--g = " << --g << endl;
cout << "Now g = " << g << endl;
}
Nov 13, 2019 at 2:33pm UTC
welcome!
put the code in format tags, edit your post to do this. <> on the side bar editor.
Describe the problem. What was the input, what was the output, and what was expected.
Debugging code is a skill you want to develop. Have you traced your code in a debugger to watch variables change, to see where things go wrong? Alternately you can use print statements to hone in on problems. A mix of the 2 ideas is useful... stepping one line at a time takes a while, so a run end to end with some key prints is quick and gives you info fast, while the debugger is more flexible and lets you root around for problems; you need both.
another useful debugging technique is to bypass all the user input with a test run. you can do this 2 ways: make a file of exactly what you type in (text file) and redirect it to the program (on the console where you run the program , program < file ) or you can hard code a test case and comment out inputs. It looks like all or most of your input is a file already, but keep this in mind for when you have cin heavy programs.
we can look too, once you explain the problem in more detail, but you should look for yourself as best you can with the above ideas too.
Last edited on Nov 13, 2019 at 2:35pm UTC
Nov 13, 2019 at 4:01pm UTC
Add
return ;
as the first line of "simplify"; i.e. make it start
1 2 3
void Fraction::simplify()
{
return ; // this will effectively stop this routine doing anything
You also need to remove the (presumably) spurious line 'fraction' that you have posted in fraction.h, or it won't compile.
Once you have safely removed the dysfunctional routine 'simplify' by doing this, your code should at least run.
Then you can start fixing it, starting with whatever mess "simplify" is. Look up GCD.
PLEASE DO ... USE CODE TAGS.
PLEASE DON'T ... POST A VAST WALL OF UNREADABLE CODE
Develop your code one routine at a time, testing as you go, not write the entire thing and presume that it will run.
Here's an alternative version of 'simplify'. You will still have errors in some of your other functions.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
#include <cstdlib>
// Reducing the fraction to its smallest form
void Fraction::simplify()
{
if (denominator < 0)
{
denominator = -denominator;
numerator = -numerator;
}
int a = abs( numerator ), b = denominator;
while ( b )
{
int temp = a;
a = b;
b = temp % b;
}
if ( a > 1 )
{
numerator /= a;
denominator /= a;
}
}
Last edited on Nov 13, 2019 at 5:27pm UTC
Nov 13, 2019 at 6:10pm UTC
+= doesn't need to call simplify() because operator+ already did.
operators ++ and -- do need to call simplify().