quadratic solver prt 2

I wrote this code for the quadratic equation but I want to know how can I use cin.fail() when someone enters an invalid character for a b or c. I don't want the program to end, I want the user to enter a correct numerical value for a b or c.
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <iostream> 
#include <cmath> 
#include <string> 
#include <iomanip>
using namespace std; 

int main() 
{
	string Name;
	double a;
	double b; 
	double c; 
	double discriminant;
	double x1; 
	double x2;
	double y;
	double z;
	cout << scientific;

cout << "\t\t\t===============================\n";
cout << "\t\t\t\tQuadratic Equation\n";
cout << "\t\t\t===============================\n";
cout << "Full Name:";
getline(cin,Name); 
cout << "\n\n"; 
cout << setw(25) << Name << "\n"; 
cout << "This program will provide solutions for an equation of the form:\n"; 
cout << "\t\ta*x^2 + b*x + c = 0\n"; 
cout << "Where a,b, and c are integers and a is not equal to zero\n"; 

cout << "Enter value of a:"; 
cin >> a; 
if(a == 0) 
{ cout << "No solutions will be calculated for a leading coefficient of 0\n"; 
exit(0);
} 
else if(a != 0)
{ cout << "Enter value of b:"; 
cin >> b; 
cout << "Enter value of c:"; 
cin >> c;
}

discriminant = pow(b,2) - 4 * a * c; 

if(discriminant > 0) 
{ abs(discriminant);
x1 = (((-b) + sqrt(discriminant))/(2*a));
x2 = (((-b) - sqrt(discriminant))/(2*a));
cout << "The two real solutions are \n x =" << x1 << "\n" << "and x =" << x2 << "\n"; 
}

else if(discriminant == 0)
{ z = (-b)/(2*a); 
cout << "The only real solution is " << z << "\n"; 
}

else if(discriminant < 0) 
{ y = discriminant * -1;
x1 = (((-b) + sqrt(y))/(2*a));
x2 = (((-b) - sqrt(y))/(2*a));
cout << "The two imagninary solutions are x = " << x1 << "*i" << "\n" << "and x = " << x2 << "*i\n"; 
}

return 0; 
}


I know I have to put this code somewhere in the overall code
1
2
3
4
5
6
7
do{
//the cin for the values a b or c are suppose to be in here somehwo
bFail = cin.fail() 

cin.clear
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}while(bFail == true);
You can use this function for input:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
template <typename T>
void validated_input(T& value, std::string message = "invalid value\n")
{
    while(!(std::cin >> value)) {
        std::cout << message;
        std::cin.clear();
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    }
}
//Usage
int a;
std::cout << "Enter a: ";
validated_input(a, "Enter number!\n");
//or
validated_input(a);
@Modern Man19

- Line 44: b * b is more appropriate than pow(b,2) !
- Line 47: why abs(discriminant) while discriminant > 0 ?
- Line 62: when discriminant < 0 the quadratic equation has two complex conjugates roots: - b / (2.0 * a) +/- i * sqrt( - discriminant) / (2.0 * a) so the line must be corrected.
If you want (really) safe number input, you should check out cire's routine here:

Trying to limit input to int type
http://www.cplusplus.com/forum/beginner/108849/#msg592118

Andy

PS The problem with the common fail/clear approach is that it admits strings which begin with a number but are not just a number. Using code below to drive MiiNiPaa's function (tweaked to prohibit negative numbers) I get, for this sequence of inputs:

12
42nd Street
3 4 5
3.14
-273
0

this output (I've enboldened the text I types in):

Enter one or more positive int values
Enter zero (0) to exit

Enter value: 12
got: 12
Enter value: 42nd Street
got: 42
Enter value: invalid value : please enter a positive integer value, or 0 to exit

3 4 5
got: 3
Enter value: got: 4
Enter value: got: 5
Enter value: 3.14
got: 3
Enter value: invalid value : please enter a positive integer value, or 0 to exit

-273
invalid value : please enter a positive integer value, or 0 to exit
0
got: 0

Whereas if I feed the same set of inputs to cire's function I get:

Enter one or more positive int values
Enter zero (0) to exit

Enter value: 12
got: 12
Enter value: 42nd Street
invalid value : please enter a positive integer value, or 0 to exit
Enter value: 3 4 5
invalid value : please enter a positive integer value, or 0 to exit
Enter value: 3.14
invalid value : please enter a positive integer value, or 0 to exit
Enter value: -273
invalid value : please enter a positive integer value, or 0 to exit
Enter value: 0
got: 0

Code listings:

#1 -- using tweaked version of MiiNiPaa's function (which now checks value is positive or zero.)

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
26
27
28
29
30
31
32
#include <iostream>
#include <string>
#include <limits>

template <typename T>
void validated_input(T& value, std::string message = "invalid value\n")
{
    while(!(std::cin >> value) || (0 > value)) {
        std::cout << message;
        std::cin.clear();
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    }
}

int main()
{
    std::cout << "Enter one or more positive int values\n"
                 "Enter zero (0) to exit\n"
                 "\n";

    int value = 0;

    do
    {
        std::cout << "Enter value: ";
        validated_input(value);
        std::cout << "got: " << value << "\n";
    }
    while(0 != value);

    return 0;
}


#2 -- with a tweaked version of cire's code (so error message is same as other version, and back ported to C++03)

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <iostream>
#include <sstream>
#include <string>
#include <limits>

template <typename T, class UnaryPredicate>
T get(const std::string& prompt, UnaryPredicate pred,
    std::string message = "invalid value\n")
{
    T result = T();

    bool notDone = true;

    while (notDone)
    {
        std::cout << prompt ;

        std::string line;
        std::getline(std::cin, line);

        std::istringstream is(line);

        char dummy;
        if (!(is >> result) || (is >> std::ws && is.get(dummy)) || !pred(result))
            std::cout << message;
        else
            notDone = false ;
    }

    return result;
}

bool is_positive_or_zero(int value)
{
    return (0 <= value);
}

int main()
{
    std::cout << "Enter one or more positive int values\n"
                 "Enter zero (0) to exit\n"
                 "\n";

    int value = 0;

    do
    {
        value = get<int>("Enter value: ", is_positive_or_zero,
            "invalid value : please enter a positive integer"
            " value, or 0 to exit\n");
        std::cout << "got: " << value << "\n";
    }
    while(0 != value);

    return 0;
}

Last edited on
Topic archived. No new replies allowed.