c++ runtime error with code (classes/constructors) - c++

I seem to be getting two errors:
A) The first iteration of the loop prints out values fine, however if I press 'y' to go for round 2 it autofills the first number as '0/0'. Shown in the image
B) I want to use the third constructor to set numerator = num and denominator = den However, it just seems to set to default values so I made a temporary fix by commenting out the constructor "Rational(num, den)" and physically wrote out numerator = num; and denominator = den;
Any help is appreciated!
// Add appropriate headers
#include <iostream>
#include <cstdlib>
#include <string>
#include <cmath>
#include <sys/time.h>
using namespace std;
/* KEEP THIS COMMENT
* class Rational
* represents a Rational number. Remember rational means ratio-nal
* which means there is a numerator and denominator having
* integer values. Using good ADT techniques, we have made member
* variable private (also known as instance variables) and made member
* functions public.
*/
class Rational
{
private:
int numerator;
int denominator;
public:
// ToDo: Default Constructor
Rational();
// ToDo: Constructor that takes int numerator
Rational(int i);
// ToDo: Constructor that takes int numerator and int denominator
Rational(int p, int q);
// ToDo: Member function to read a rational in the form: n/d
void input();
// ToDo: Member function to write a rational as n/d
void output();
// ToDo: declare an accessor function to get the numerator
int getNumerator();
// ToDo: declare an accessor function to get the denominator
int getDenominator();
// ToDo: delcare a function called Sum that takes two rational objects
// sets the current object to the sum of the given objects using the
// formula: a/b + c/d = ( a*d + b*c)/(b*d)
void sum(Rational a, Rational b);
// test if two rational numbers are equal.
bool isEqual(const Rational& op);
};
int main()
{
// ToDo: declare three rational objects using the default constructor
Rational a, b, c;
char answer='Y';
// Main loop to read in rationals and compute the sum
do {
cout << "\nEnter op1 (in the format of p/q): ";
a.input();
//Debug line
a.output();
// ToDo: use your input member function to read the first rational
cout << "\nEnter op2 (in the format of p/q): ";
// ToDo: use your input member function to read the second rational
b.input();
//Debug line
b.output();
// ToDo: use the third rational to call Sum with first and second as parameters
c.sum(a, b);
cout << "\nThe sum of op1 and op2 is: ";
c.output();
// ToDo: ouptput the third rational
cout << endl;
cout << "\nTry again (Y/N)?";
cin >> answer;
} while (answer == 'y' || answer == 'Y');
// ToDo: test getters
cout << "\nC's numerator is: " << c.getNumerator() << endl;
cout << "\nC's denominator is: " << c.getDenominator() << endl;
// TODO: Use two constructors to declare a whole number 3/1 and a 4/5
// TODO: Use output to print both rationals
//cout << .output() << " " << .output() << endl;
return 0;
}
// ToDO: Implement your class member functions below.
Rational::Rational()
{
numerator = 0;
denominator = 1;
}
Rational::Rational(int i)
{
numerator = i;
denominator = 1;
}
Rational::Rational(int p, int q)
{
numerator = p;
denominator = q;
}
void Rational::sum(Rational a, Rational b)
{
int num = (a.numerator*b.denominator + a.denominator*b.numerator);
int den = (a.denominator*b.denominator);
numerator = num;
denominator = den;
}
void Rational::input()
{
string in;
int num,den;
//cout << "Enter a rational number in the form of x/y : ";
getline(cin, in);
// find the index position of /
int indx = in.find("/");
// seperator out the numerator
num = atoi(in.substr(0, indx).c_str());
// seperate out the denominator
den = atoi(in.substr(indx+1, in.length()).c_str());
// Rational(num, den);
//cout <<num << " " <<den << endl; // Debug Line
numerator = num;
denominator = den;
//cout <<numerator << " " <<denominator << endl; // Debug Line
}
void Rational::output()
{
cout << numerator << "/" << denominator;
}
// Two getter functions
int Rational::getNumerator()
{
return numerator;
}

Here is the solution. Let me know if you don't know what Buffer is or why do we flush it. I'll try to explain further.
cout << "\nTry again (Y/N)?"; //In main
cin >> answer;
cin.ignore(256,'\n'); // Flush the buffer
Here is the explanation.
Yeah, it(cin) will work fine, As cin doesn't have any issue with buffer. But the issue is with getline. Now let's explain why. First, you need to know how the computer takes input in the program. Whenever you cin some value like cin>>x. The value doesn't directly go into x. Firstly it is stored in some temporary location named buffer. That's why you can press backspace on your console. If it directly writes in more variable(memory), you can't press backspace. It means suppose entering string you wrote "appke", but you want to write "apple " you can press backspace(until you haven't pressed enter). Now, what happens you take input with cin as you give input and press Enter for the next input. Like in your case you pressed "y" and then enter(which is denoted by "\n"). So as enter data it goes into the buffer and then you press enter that enter also goes into buffer but system picks only data from buffer like "y" in your case. So your buffer still has "\n" from previous data. Now come to getline. It has one parameter named "delim" [See-here]http://www.cplusplus.com/reference/string/string/getline/ who tells getline when to stop taking input. By default its values is "\n". Now from your previous entry, your buffer has already "\n" in it. So as getline comes in contact with the buffer, it sees "\n", and it thinks that data for input is present as he finds "\n" in the buffer which is the indicator when to stop. That's why it didn't ask for input. Now come to a solution. If ever you think to use getline after cin. All you need to do is to remove "\n" from the buffer. So all you do is cin.ignore("\n"). You are asking cin to ignore "\n" which was present in the buffer. So when control goes to getline. It ignores the already present "\n" in the buffer and works normally.

Related

Keep asking for user input until condition met C++

I'm trying to write a script where the user will be inputting a radius and then the console will display the Volume and Surface Area of a sphere. If the input radius is negative, the user will be prompted to enter a positive radius until the condition is met. I've managed to do this but without validating the positive radius bit. How can I achieve this?
My code:
/*
* Calculate the volume and surface area of a sphere.
*
*/
#include <iostream>
#include <string>
#include <sstream>
#include <cmath> // Include cmath for M_PI constant
using namespace std;
int main()
{
const double pi = M_PI; /// Value of PI defined by C++
string input = ""; /// Temporary input buffer
double r = 0.0; /// Sphere radius
double A = 0.0; /// Sphere area
double V = 0.0; /// Sphere volume
// Request radius
cout << "Please enter radius of sphere (positive only): ";
// Get string input from user (up to next press of <enter> key)
getline(cin, input);
// Try to convert input to a double
r = stod(input);
// making sure r is positive
if (r > 0)
{
// Calculate area and volume
// Ensure floating-point division instead of integer division by
// explicitly writing 4.0/3.0
A = 4.0 * pi * r * r;
V = (4.0 / 3.0) * pi * r * r * r;
// Write out result
cout << "Sphere radius: " << r << endl;
cout << "Sphere area: " << A << endl;
cout << "Sphere volume: " << V << endl;
}
else
{
while (r < 0)
{
cout << "Please enter radius of sphere (positive only): " << endl;
}
}
// Return success
return 0;
}
First, this code is not awful. Compared to what I've seen from some other beginners, this code demonstrates that there is a decent understanding of fundamentals up to this point.
The biggest issue facing your code is the order of operations. If you want input from the user, you need to validate it before processing it. Currently, you're doing a bit of both at the same time. As mentioned, create a loop that does not exit until you have valid inputs. Then go ahead and do your math. This is separating your concerns and is a best practice.
Other nitpicks include using namespace std; as a bad practice, and one you should get out of doing sooner than later. Front-declaring your variables is also bad practice. Declare at or near first use. std::string input; suffices for a default string, there is no need to = "";.
And as I commented, stod() can throw an exception and abort your program if the input cannot be converted. You don't mention whether you're allowed to assume your input will always be a number or not so I can't assume it is.
/*
* Calculate the volume and surface area of a sphere.
*
*/
#include <cmath>
#include <iostream>
#include <numbers>
#include <string>
int main() {
double radius = 0.0;
bool inputIsInvalid = true;
do {
std::string input;
std::cout << "Enter a radius: ";
std::getline(std::cin, input);
std::size_t pos = 0;
try {
radius = std::stod(input, &pos);
} catch (const std::exception& e) {
std::cerr << "Unable to convert to double. Reason: " << e.what() << '\n';
continue;
}
// We're still not done checking. We need to ensure that the entire string
// was converted. If not, the input was invalid.
if (pos != input.length()) {
std::cerr << "Invalid characters added. Try again.\n";
continue;
}
// Making it here means a valid double was typed in.
// Now we ensure that the double is positive.
if (radius < 0.0) {
std::cerr << "Please enter a positive number. Try again.\n";
continue;
}
// Making it here should mean that we have a valid input.
inputIsInvalid = false;
} while (inputIsInvalid);
// Now we can do math!
using namespace std::numbers; // C++20 stuff for pi
double surfaceArea = 4.0 * pi * std::pow(radius, 2);
double volume = (4.0 / 3.0) * pi * std::pow(radius, 3);
std::cout << "For a sphere of radius: " << radius << '\n'
<< "Surface area: " << surfaceArea << '\n'
<< "Volume: " << volume << '\n';
}
Output:
❯ ./a.out
Enter a radius: foo
Unable to convert to double. Reason: stod: no conversion
Enter a radius: 3o
Invalid characters added. Try again.
Enter a radius: -3
Please enter a positive number. Try again.
Enter a radius: 3
For a sphere of radius: 3
Surface area: 113.097
Volume: 113.097
As you can see, all of the getting of input and validation occurs within the big do/while loop. If we are out of the loop, we know that we have a valid value, and doing the math is now very straightforward.
There is no need for complicated statements.
You just need to understand that IO operation notice, when there was a problem. And then they set failure bits, which you can check.
Please look in the CPP reference at this link. There is a long description of what could happen and what failure bit will be set and how it can be tested.
So, if you use for example the stand extraction operator >> like in std::cin >> radius then this operator will try to read a value from the console and convert it to a double. If it cannot do that, because you entered for example "abc" instead of a number, a failure bit will be set. The std::cinis then in state fail and does not work any longer.
If you want to continue to use std::cin then you must clear the fail bits with the clear() function. So, you need to write std::cin.clear();.
But this is not sufficient. There might be still some other characters in the input buffer. And those need to be removed. Imagine that you enter "XYZ" instead of a number, then std::cin will go into failure state after reading the first character 'X'. We need to eliminate all the wrong characters, because otherwise, they will be read again with the next >> operation.
For this we have the function ignore. Please read here about the function and look at the example at the bottom of the page. Exactly what you need.
Next: How can we check for an error of an IO operation?
You may have heard that we can chain IO operations. For example: int a,b; std::cin >> a >> b; or, for the output case std::cout << value << "\n";
Why does this work? You need to understand the the extraction and inserter operator >> and << return a reference to the stream for which they have been called.
So, std::cin >> a; will return a reference to std::cin. And that is the reason why you can chain IO operations.
std::cin >> a >> b; will first do std::cin >> a which will return std::cin. The rest of the expression will now be std::cin >> b;. also this will be performed and again std::cin will be returned.
And this we can use. The basic:ios has 2 operators to check the failure state.
the bool operator
the not operator !
So, you can check the state of std::cin simply with if (std::cin). And because the if-statement expects a bool expression, it will call the streams bool operator. And with that get the state.
And now, what we learned above: if (std::cin >> a) will try to read a value into "a" then return std::cin and then its bool operator is called.
Now we found a possibility to check for a correct IO operation with if (std::cin >> radius) But of course we can do more test in the if statement. You have often seen and && or or|| operators in conditions. You can make use of it. And especially you can make use of boolean shortcut evaluation.
Meaning, if the outcome of a condition is already clear by evaluation the first term, then the second term will not be evaluated.
So, we can write if ((std::cin >> radius) and (radius > 0.0)) to check for a valid input. If the reading of the input fails, then the check for greater than 0 will not be executed. It will only be executed, if the input was successful.
With all the above, we can now draft the below very simple solution:
#include <iostream>
#include <limits>
int main() {
double radius = 0.0;
bool valueOK = false;
while (not valueOK) {
std::cout << "\n\nInsert radius. A positive value: ";
if ((std::cin >> radius) and (radius > 0.0))
valueOK = true;
else {
std::cout << "\n\n***Error: invalid input\n";
}
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
const double PI = 3.14159265358979323846;
std::cout << "\n\nSphere Radius:\t" << radius
<< "\nSphere area:\t" << 4.0 * PI * radius * radius
<< "\nSphere volume:\t" << 4.0 / 3.0 * PI * radius * radius * radius << '\n';
}
No need for complicated statements.
You could use std::from_chars within an infinite loop to read a radius of type double (see here):
It receives a couple of const char* to the beginning and end of the string you want to parse, and a reference to a double value (that will be set if the parsing went OK).
It returns a pointer pointing to the first character that didn't match the pattern for a double value, and an error.
If the error is "empty" (just value-initialized), and the pointer points to the end of the input string, it means that all the characters were used to parse the double value (i.e. there were no extra characters at the beginning or at the end in the input string).
[Demo]
#include <charconv> // from_chars
#include <iostream> // cin, cout
#include <numbers> // Include cmath for M_PI constant
#include <sstream>
#include <string> // getline
#include <system_error> // errc
int main() {
// Request radius
double r = 0.0; /// Sphere radius
for (;;) {
std::cout << "Please enter radius of sphere (positive only): ";
// Get string input from user (up to next press of <enter> key)
std::string input = ""; /// Temporary input buffer
getline(std::cin, input);
std::cout << input << "\n";
// Try to convert input to a double
auto [ptr, ec] = std::from_chars(input.data(), input.data() + input.size(), r);
if (ec != std::errc{} or ptr != input.data() + input.size() or r < 0) {
std::cout << "Invalid input: '" << input << "'\n";
} else {
break;
}
}
// Calculate area and volume
// Ensure floating-point division instead of integer division by
// explicitly writing 4.0/3.0
double A = 4.0 * std::numbers::pi_v<double> * r * r; /// Sphere area
double V = (4.0 / 3.0) * std::numbers::pi_v<double> * r * r * r; /// Sphere volume
// Write out result
std::cout << "Sphere radius: " << r << "\n";
std::cout << "Sphere area: " << A << "\n";
std::cout << "Sphere volume: " << V << "\n";
// Return success
return 0;
}
// Outputs:
//
// Please enter radius of sphere (positive only): -5
// Invalid input: '-5'
// Please enter radius of sphere (positive only): hola
// Invalid input: 'hola'
// Please enter radius of sphere (positive only): 25abc
// Invalid input: '25abc'
// Please enter radius of sphere (positive only): 1.5
// Sphere radius: 1.5
// Sphere area: 28.2743
// Sphere volume: 14.1372

How to split a fraction into two integers c++

I'm working on an assignment. I need to have the user input a fraction in #/# format . How can I set the top and bottom to two separate variables?
Here's a chunk of code I've tried, but I keep getting nothing for the second variable:
#include <iostream>
#include <conio.h>
#include <cstdio>
#include <regex>
using namespace std;
int main() {
string firstFraction;
cout << "Enter your first real Fraction: " << endl;
firstFraction = cin.get();
string delimiter = "/";
string numerator = firstFraction.substr(0,firstFraction.find(delimiter));
size_t pos = firstFraction.find("/");
string denominator = firstFraction.substr(pos);
cout << numerator << " / " << denominator << endl;
_getch();
return 0;
}
Try something like this:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main() {
string fraction;
cout << "Enter your first real Fraction: " << endl;
getline(cin, fraction);
istringstream iss(fraction);
string numerator, denominator;
getline(iss, numerator, '/');
getline(iss, denominator);
cout << numerator << " / " << denominator << endl;
cin.get();
return 0;
}
firstFraction = cin.get();
Print firstFraction after this line and see whether it contains what you thought it contains. Looking in the reference (something you should be doing!) ...
[..] Reads one character and returns it if available. [..]
... we learn that you're only reading a single character (of unformatted input). How do you intend to split the resulting (single character) string?
There are multiple ways of doing it correctly, which one to choose depends a lot on your needs. A short, non-complete list:
std::getline the whole line, and then searching for / within it
std::getline until the next /, std::getline until end of line. (I don't really recommend this)
Formatted input, for example :
#include <iostream>
using namespace std;
int main() {
unsigned int nominator, denominator;
char sep;
cin >> nominator >> sep >> denominator;
if (!cin || sep != '/') {
cerr << "Well... you know, that failed somehow." << endl;
return 1;
}
cout << "Fraction: " << nominator << "/" << denominator << endl;
return 0;
}
Though this also allows input like
3 / 4
and
3
/
4
And of course, you should abstract this, e.g. make a fraction class, and write a (member) function read_fraction (and also provide a suitable operator>> if you want).
This could be as simple as
#include <iostream>
#include <sstream>
#include <string>
//using namespace std; dangerous! Use with caution
int main()
{
int num; // want a number as numerator
int denom; // and a number as denomenator
char divsign; // and a character to hold the /
std::cout << "Enter your first real Fraction: " << std::endl;
// user input contains at least a numerator a / and a denominator
// anything less fails. anything more will slip through. If this is a
// problem, add another >> to see if there is more in the stream
if (std::cin >> num >> divsign >> denom && // all input read successfully
divsign == '/') // and the division operator was present
{ // got what we need. Print it.
std::cout << num << " / " << denom << std::endl;
}
else
{ // bad input. insult user.
std::cout << "Bogus user input. No fraction for you" << std::endl;
}
return 0;
}
It has a number of potential failure cases, such as:
999999999999 / 2
Bogus user input. No fraction for you
Integer overflow. The input was too big. And
1/1dfjklghaljkgadlfhjgklahd
1 / 1
Crap after the last character

Print function in a class not updating when boolean is updated

So I have a program for a class that Im writing that is all done except for the print function. The input function is correct and the boolean value will update in the input function but when i try to transfer to the print function it always prints (-) and if the user enters 'Y' then it is suppose to bypass the (-) and just print out the fraction. If anyone has anyway to get it to work, I feel like ive tried everything.
Edit: The print function works when i print out just the two fractions in main which are f1 and f2 but the problem is coming when passing the positive into the print function i believe.
class fraction
{
private:
int numerator;
int denom;
bool positive;
public:
void inputFrac();
void printFrac();
fraction fracMult(fraction& b);
fraction fracDiv(fraction& b);
fraction fracAdd(fraction& b);
fraction fracSub(fraction& b);
};
void fraction::printFrac()
{
if (positive=true)
{
cout << "-" << numerator << " / " << denom;
}
else
{
cout << "+" << numerator << " / " << denom;
}
}
void fraction::inputFrac()
{
char tempchar1;
fraction tempchar;
cout<<"Please input the numerator ";
cin>>numerator;
cout<< "Please input the denominator ";
cin>>denom;
cout<<"Is the fraction positive? (Y or N) ";
cin>>tempchar1;
if((tempchar1=='Y'))
{
positive=true;
}
else
{
positive=false;
}
}
You're assigning within your if statement.
Change:
if (positive=true)
to:
if (positive==true)
In your printFrac function, you have if (positive=true). This is incorrect, for what you are doing. You should instead have if (positive) {/*stuff*/}.

Comparing smallest user input for C++

I tried to find the smallest number within 3 inputs. Here is my codes :
int main ()
{
double x = 4.0;
double y = 5.0;
double z = 3.0;
smallest(x,y,z);
cout << smallest << endl;
system("PAUSE");
}
double smallest(double x, double y, double z)
{
double smallest;
if ((x < y)||(x< z)) {
smallest = x;
} else if ((y < z)||(y < x)) {
smallest = y;
} else {
smallest = z;
}
return smallest;
}
However, I keep getting error. It stated that my smallest method in main method with undeclared identifier. This works when using eclipse but not visual studio. Can somebody explain to me why?
Thanks in advance.
Updated portion.
So I tried to do validation for this program. I want to ensure users only enter number and here are my codes :
double x, y, z;
bool correct_input = false;
do{
cout << "Enter first integer : " ;
cin >> x;
if(isdigit(x)){
correct_input = true;
}
}while(!correct_input);
do{
cout << "Enter second integer : ";
cin >> y;
if(isdigit(y)){
correct_input = true;
}
}while(!correct_input);
do{
cout << "Enter third integer : ";
cin >> z;
if(isdigit(z)){
correct_input = true;
}
}while(!correct_input);
cout << "Smallest integer is : " << smallest(x,y,z) << endl;
system("PAUSE");
When I entered alphabet or whatever except numbers, I get debug assertion failed. It does not prompt until user enter correct input. Can somebody help?
First of all, if you wish to use smallest() before it's defined, you need to prototype it. Add the following before main():
double smallest(double x, double y, double z);
Also, you are ignoring the return value of smallest(). Change
smallest(x,y,z);
cout << smallest << endl;
to
double smallest_val = smallest(x,y,z);
cout << smallest_val << endl;
This isn't the question you asked but your function is bugged because you confused || and &&.
Your function should be
double smallest(double x, double y, double z)
{
double smallest;
if (x < y && x < z)
smallest = x;
else if (y < z && y < x)
smallest = y;
else
smallest = z;
return smallest;
}
x is the smallest number if it is less y and it is less than z.
update
First thing to say is that if you want integers then you should be using int not double.
Second thing, isdigit doesn't do what you think it does. You've actually set yourself a very difficult problem. Here's one way to do it
#include <string> // for string class
bool correct_input = false;
do
{
cout << "Enter first integer : " ;
if (cin >> x)
{
correct_input = true;
}
else
{
// cin is in a error state after a failed read so clear it
cin.clear();
// ignore any remaining input to the end of the line
string garbage;
getline(cin, garbage);
}
}
while(!correct_input);
But this doesn't work perfectly. For instance if you enter abc then your program will ask for more input, but if you enter 123abc, then you will get the integer 123 even though 123abc is not a valid number.
If you really want to do this properly (and it is hard) then you must read in a string, check if the string could be converted to a number, if it can then do the conversion, if it can't then ask for more input.
Put this line above your main ;).
double smallest(double x, double y, double z);
You need to declare any function you make. This is called making a function header.
You should declare you function so that the compiler can recognize it.
Put its prototype above main function as this:
double smallest(double, double, double);
int main()
{
//Staff
}
There are two problem, here, one related to how to get the smallest, and the other related to ho get correct input.
For the first problem, let me propose a recursive approach:
// this is trivial
double smallest(double x, double y)
{ return (x<y)? x: y; }
// the smalles of three is the smallest between the smallest of two and the third
double smallest(double x, double y, double z)
{ return smallest(smallest(x,y),z); }
For the second problem, you have the same problem for each of the variables, so let's make a function for it:
#include <iostream>
#include <limits>
#include <string>
double read(std::istream& s, std::ostream& o, const std::string& message)
{
for(;;) //stay here until kiked out
{
double d=0.; //just a safe value - no particular meaning
o << message << std::endl; // prompt the request
bool good(s >> d); //read a double and keep the state
if(!good) s.clear(); //if we failed to read, clean the stream state
//in any case, discard everything unread until the return.
s.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
if(good) return d; //if reading succeeded, return.
//overwise loop back
}
}
This is based on the fact the std::cin have a state that is set to "bad" is the input cannot be read in the given variable.
We just read, and, if it fails, redo again and again.
But fist we have to clear the state, so thet the input can be unlocked.
Independently og good an bad reading, we have then to discard everuthing "extra" that can be typed in the line (think to 123asdf: we successfully read 123, but we have to discard abc)
The the reading was successful we just return it, otherwise we loop over and over until we get it.
The program itself, at this point will reduce to:
int main()
{
double x = read(std::cin, std::cout, "Enter first value");
double y = read(std::cin, std::cout, "Enter second value");
double z = read(std::cin, std::cout, "Enter third value");
std::cout << "the smallest numer is: " << smallest(x,y,z) << std::endl;
return 0;
}
that can run this way:
Enter first value
7
Enter second value
5.2yyyy
Enter third value
sf3
Enter third value
455
the smallest numer is: 5.2
A more advanced technique can be transform the function into a manipulator class, like this:
class read_value
{
public:
read_value(double& d, const std::string& prompt_, std::ostream& out_ = std::cout)
:z(d), prompt(prompt_), outstream(out_)
{}
friend std::istream& operator>>(std::istream& s, const read_value& a)
{
for(;;)
{
a.outstream << a.prompt << std::endl; // prompt the request
bool good(s >> a.z); //read a double and keep the state
if(!good) s.clear(); //if we failed to read, cleanr the stream state
//in any case, discard everything unread until the return.
s.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
if(good) return s; //if reading succeeded, return.
//overwise loop back
}
}
private:
double& z;
std::string prompt;
std::ostream& outstream;
};
letting the program a more idiomatic form:
int main()
{
double x,y,z;
std::cin >>
read_value(x,"Enter first value") >>
read_value(y,"Enter second value") >>
read_value(z,"Enter third value");
std::cout << "the smallest numer is: " << smallest(x,y,z) << std::endl;
return 0;
}
Another point can be the fact the user can loop forever by never typing a good sequence.
We can fix a maximum attempt limit introducing a counter in the for loop, and setting the input to "failed" if the loop terminates without returning:
friend std::istream& operator>>(std::istream& s, const read_value& a)
{
for(int i=0; i<10; ++i)
{
... //same as before
}
return s; //s will be returned in failed state
}
And then checking in the main program:
int main()
{
double x,y,z;
std::cin >>
read_value(x,"Enter first value") >>
read_value(y,"Enter second value") >>
read_value(z,"Enter third value");
if(!std::cin)
{
std::cout << "bad input." << std::endl;
return -1; //report as "program failed"
}
std::cout << "the smallest numer is: " << smallest(x,y,z) << std::endl;
return 0; //succeeded
}
.

How to reduce/simplify fractions completely (C++)

I cannot for the life of me fathom why I'm getting infinite values returned when I input a normal fraction into the code. Everything but the GCD (Greatest common divisor) seems to be working.
Is there a blatantly obvious logic error somewhere within this?
I've done my research and found various answers to the question, I mean Wikipedia even GIVES YOU code to do it, but I'd like to figure out how to make it work the way I've coded it the way it is now.
#include <iostream>
#include <stdlib.h>
#include <cmath>
#include <math.h>
using namespace std;
class Fraction
{
private:
double num;
double den;
double fraction;
double temp;
public:
void setNum();
void setDen();
int getNum();
int getDen();
void lcdOutput();
void decOutput();
int gcd();
};
void Fraction::setNum(){
cout << "Enter a value for your numerator: " << endl;
cin >> num;
}
void Fraction::setDen(){
cout << "Enter a value for your denominator: " << endl;
cin >> den;
}
int Fraction::getNum(){
return num;
}
int Fraction::getDen(){
return den;
}
int Fraction::gcd(){
Fraction set;
if(num > den){
if(fmod(num, den) == 0){
den = temp;
return temp;
}
else{
den = fmod(num, den);
set.gcd();
}
}
else{
if(fmod(den, num) == 0){
num = temp;
return temp;
}
else{
num = fmod(den, num);
set.gcd();
}
}
}
void Fraction::lcdOutput(){
Fraction set;
set.gcd();
num = num / temp;
den = den / temp;
cout << "Fraction in lowest terms: " << num << "/" << den << endl;
}
void Fraction::decOutput(){
double decimal = num / den;
cout.precision(4);
cout << "The fraction in decimal form is: " << decimal << endl;
}
int main(){
Fraction set;
set.setNum();
set.setDen();
set.getNum();
set.getDen();
set.lcdOutput();
set.decOutput();
return 0;
}
Here's what I can determine just by stepping through your code.
Starting at main, you instantiate an instance of type Fraction named set. You assign its numerator and denominator via calls to set.setNum() and set.setDen(). The calls to getNum() and getDen() do nothing in this case, as they are not being assigned to anything.
Then you call lcdOutput(), so let us begin stepping through that.
You begin by instantiating a LOCAL instance of Fraction (not sure why you want to do this, it appears to me that this may be a conceptual mistake), and then call set.gcd() for that local instance. Calling set.gcd() will call the method for THAT INSTANCE, and it seems to me that what you really want is this->gcd() or simply gcd().
You follow up by setting num = num / temp and den = den / temp, but temp is still uninitialized at this point. If the variable is left uninitialized, it can (and usually is) pointing to garbage. This probably explains why you are getting nonsensical values returned.
I went back and figured it out on my own. I saw some of the comments and noticed my very large conceptual and logical errors. Here's to anyone that has the same question!
int gcd(double num, double den){
if(den == 0){
return num;
}
return gcd(den, fmod(num, den));
}
void Fraction::lcdOutput(){
double temp = gcd(num, den);
cout << "Fraction in lowest terms: " << num / temp << "/" << den / temp << endl;
}