error prevention

Thread Starter

mentaaal

Joined Oct 17, 2005
451
Hi all,

Everytime i have made a program and received an input from the user, such as:

int choice;
cout << " Please enter 1 for addition or 2 for subtraction.\n";
cin >> option;

if the user's input is not a number like say for example the user decides to press a letter iinstead of a number, the program would go into an infinite loop. Is there any way of preventing an error such as this?

Thanks,
Greg
 

hgmjr

Joined Jan 28, 2005
9,027
Can you provide us with the code that you are using so that we can see firsthand how you are handling the input?

hgmjr
 

beenthere

Joined Apr 20, 2004
15,819
There are several ways to prevent such things from killing your code. You have to test each input to see if it is within an expected range.

If your language had a SELECT CASE structure, for instance, then something like this might work:

SELECT CASE input (where input is the variable holding the input character)
Case 1
Set addition flag to true
Case 2
Set subtraction flag true
Case Else
input = 0
END SELECT

You could also do a couple of IF - THEN test to eliminate all inputs except 1 or 2.

Never let an unexamined input affect program execution.
 

Thread Starter

mentaaal

Joined Oct 17, 2005
451
Ok well this is the code i made for a homework question.
If i press a letter key anywhere in this program it will loop:

Rich (BB code):
#include <iostream>
using namespace std;
void feet2metres(float, float&);
void metres2feet(float, float&);
void menu();
void displayresults(float,float,int);

void main()
{
    menu();
}

void menu()

{
    float var1,var2;
    int option;
    char goagain;
     cout << "Welcome to the distance converter.\n";
    do
    {
        do
        {
            cout << "Please press 1 if you wish to convert from metres to feet.\n"
                 << "Please press 2 if you wish to convert from feet to metres.\n";
            cin >> option;
        }
        while (option != 1 && option != 2);
        switch (option)
         {
            case 1:
            do
            {
                cout << "Please enter the distance in metres.\n";
                cin >> var1;
                metres2feet(var1,var2);
                displayresults(var1,var2,option);
            }
            while (var1 < 0);
            break;
            case 2:
            do
            {
               cout << "Please enter the distance in feet.\n";
               cin >> var1;
               feet2metres(var1,var2);
               displayresults(var1,var2,option);
             }
            while (var1 < 0);
            break;
          
            default:
            cout << "Invalid Option.\n";
         }
        do
        {
            cout << "Would you like to go again? (Y/N)\n";
            cin >> goagain;
        }
        while (goagain != 'Y' && goagain !='y' && goagain != 'N' && goagain != 'n');
        
    }
    while (goagain == 'Y' || goagain == 'y');
}

void feet2metres(float var1, float &var2)
{
 var2 = (0.3048*var1);
}
void metres2feet (float var1, float &var2)
{
    var2 = (1/0.3048)*var1;
}

void displayresults(float var1, float var2, int option)
{
    cout.setf(ios::fixed);
    cout.setf(ios::showpoint);
    cout.precision(3);
    switch (option)
    {
        case 1:
            cout << var1 << " metres is: " << var2 << " feet.\n";
            break;
        case 2:
            cout << var1 << " feet is: " << var2 << " metres.\n";
            break;
        default:
            cout << "Invalid option.\n";
    }
}
 

SgtWookie

Joined Jul 17, 2007
22,230
When posting source code, you should use the code /code tags so that your original formatting is preserved.

Rich (BB code):
#include <iostream>
using namespace std;
void feet2metres(float, float&);
void metres2feet(float, float&);
void menu();
void displayresults(float,float,int);

void main()
{
    menu();
}

void menu()

{
    float var1,var2;
    int option;
    char goagain;
     cout << "Welcome to the distance converter.\n";
    do
    {
        do
        {
            cout << "Please press 1 if you wish to convert from metres to feet.\n"
                 << "Please press 2 if you wish to convert from feet to metres.\n";
            cin >> option;
        }
        while (option != 1 && option != 2);
        switch (option)
         {
            case 1:
            do
            {
                cout << "Please enter the distance in metres.\n";
                cin >> var1;
                metres2feet(var1,var2);
                displayresults(var1,var2,option);
            }
            while (var1 < 0);
            break;
            case 2:
            do
            {
               cout << "Please enter the distance in feet.\n";
               cin >> var1;
               feet2metres(var1,var2);
               displayresults(var1,var2,option);
             }
            while (var1 < 0);
            break;
          
            default:
            cout << "Invalid Option.\n";
         }
        do
        {
            cout << "Would you like to go again? (Y/N)\n";
            cin >> goagain;
        }
        while (goagain != 'Y' && goagain !='y' && goagain != 'N' && goagain != 'n');
        
    }
    while (goagain == 'Y' || goagain == 'y');
}

void feet2metres(float var1, float &var2)
{
 var2 = (0.3048*var1);
}
void metres2feet (float var1, float &var2)
{
    var2 = (1/0.3048)*var1;
}

void displayresults(float var1, float var2, int option)
{
    cout.setf(ios::fixed);
    cout.setf(ios::showpoint);
    cout.precision(3);
    switch (option)
    {
        case 1:
            cout << var1 << " metres is: " << var2 << " feet.\n";
            break;
        case 2:
            cout << var1 << " feet is: " << var2 << " metres.\n";
            break;
        default:
            cout << "Invalid option.\n";
    }
}
My C is mighty rusty, but... you're testing for numeric values when the input may very well not be numeric. Try testing against char values instead.
 

Thread Starter

mentaaal

Joined Oct 17, 2005
451
Thanks sgtwookie, sounds like a good idea. I definitely will insert code in a code window, its just that i didnt know how to do it before but i fiddled and now i do!
 

Thread Starter

mentaaal

Joined Oct 17, 2005
451
Hey guys, i have done what was suggested and used a char for the menu options. I however want to take this to the next level and include error prevention for the float input. As it stands, when a letter is input for when the program asks for a value, the program goes into an infinite loop. How do i stop this from happening? Must strings be used? I tried doing this but am not really sure what I am doing.


Rich (BB code):
/*  
    Homework assignment
    Gregory Kuhn
    Student ID: 20027104
*/

#include <iostream>
using namespace std;
void feet2metres(float, float&);
void metres2feet(float, float&);
void menu();
void displayresults(float,float,char);

void main()
{
    menu();
}

void menu()

{
    float var1,var2;
    char option; //a char is used here as a error prevention technique to 
                 //stop the program from going into an infinite loop whenever a letter is pressed
    char goagain;
     cout << "Welcome to the distance converter.\n";
    do
    {
        do
        {
            cout << "Please press 1 if you wish to convert from metres to feet.\n"
                 << "Please press 2 if you wish to convert from feet to metres.\n";
            cin >> option;
        }
        while (option != '1' && option != '2');
        switch (option)
         {
            case '1':
            do
            {
                cout << "Please enter the distance in metres.\n";
                cin >> var1;
                metres2feet(var1,var2);
                displayresults(var1,var2,option);
            }
            while (var1 < 0);
            break;
            case '2':
            do
            {
               cout << "Please enter the distance in feet.\n";
               cin >> var1;
               feet2metres(var1,var2);
               displayresults(var1,var2,option);
             }
            while (var1 < 0);
            break;
          
            default:
            cout << "Invalid Option.\n";
         }
        do
        {
            cout << "Would you like to go again? (Y/N)\n";
            cin >> goagain;
        }
        while (goagain != 'Y' && goagain !='y' && goagain != 'N' && goagain != 'n');
        
    }
    while (goagain == 'Y' || goagain == 'y');
}

void feet2metres(float var1, float &var2)
{
 var2 = (0.3048*var1);
}
void metres2feet (float var1, float &var2)
{
    var2 = (1/0.3048)*var1;
}

void displayresults(float var1, float var2, char option)
{
    cout.setf(ios::fixed);
    cout.setf(ios::showpoint);
    cout.precision(3);
    switch (option)
    {
        case '1':
            cout << var1 << " metres is: " << var2 << " feet.\n";
            break;
        case '2':
            cout << var1 << " feet is: " << var2 << " metres.\n";
            break;
        default:
            cout << "Invalid option2.\n";
    }
}
 

Mark44

Joined Nov 26, 2007
628
Greg,
If you want to bullet-proof your input, you'll need to accept string input for your numeric values, and then parse it into numbers. You can use atof() or atof() in the standard library to do the conversion for you. Be sure to #include <stdlib.h>.The first function takes a string argument and returns a float. The second takes a string argument and returns a double. The idea is to ask for a, say, float value, and store it in a string, convert the string to a float value (atof()) or double value (atod()), check that the value entered is legitimate (each returns 0.0 for invalid data). If the value is reasonable, off you go; otherwise you can loop back and try again. It's a bit of extra work.

OTOH, you have to assume some intelligence on the part of the user, and that if the user persists in entering weird data, your program at least has enough idiot-proofing to go down gracefully.
Mark
 

Thread Starter

mentaaal

Joined Oct 17, 2005
451
Hi mark,
thats exactly what i guessed had to be done but had no idea on how to do it! Thanks for sending me in the right direction, i was trying to look up string name.compare but was getting nowhere haha.
 
Top