Reputation: 177
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?
Upvotes: 0
Views: 466
Reputation: 20730
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
}
.
Upvotes: 0
Reputation: 87957
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.
Upvotes: 5
Reputation: 2509
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
}
Upvotes: 0
Reputation: 500457
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;
Upvotes: 6
Reputation: 443
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.
Upvotes: 0