ArthurA
ArthurA

Reputation: 21

C++ Checking input of cin for proper data

Hello I am working on a program that is checking the users input and asking for the user to reinput if the data does not match the type the program is looking for (In this case I am looking for the double data type). Below is my current code.

#include <iostream>
using namespace std;


int main()
{
    //Declare Variables and define.
    double var1,
           var2,
           var3,
           var4,
           var5,
           sum,
           avg;



        cout << "Input Five Values to be averaged. Press Enter to Continue" << endl;

    do {
        cin.clear();
        cin.ignore();
        cout << "Input first value:" << endl;
        cin >> var1;


    } while(cin.fail());

    do {
        cin.clear();
        cin.ignore();
        cout << "Input second value:" << endl;
        cin >> var2;


    } while (cin.fail());



    do {
        cin.clear();
        cin.ignore();
        cout << "Input third value:" << endl;
        cin >> var3;


    } while (cin.fail());



    do {
        cin.clear();
        cin.ignore();
        cout << "Input Fouth value:" << endl;
        cin >> var4;


    } while (cin.fail());


    do {
        cin.clear();
        cin.ignore();
        cout << "Input fifth value:" << endl;
        cin >> var5;


    } while (cin.fail());




//Sum the values.
sum = var1 + var2 + var3 + var4 + var5;

//Calculate the Average of Sum.
avg = sum / 5;

// Display the results.
cout << "The average is: " << avg << endl;

system("pause");


return 0;
}

The problems come when I input "aa", "s2", of "2ss" it will not ask for the data again once, but for as many characters are in the cin, or in the case of "s2"/"22s" it will go to the next input request. Why is this happening and how can I correct the behavior?

Thank you in advance!

Upvotes: 0

Views: 235

Answers (2)

jwm
jwm

Reputation: 1844

The other, better answers explained how to make it stop. This is why it's happening:

double d;
cin >> d;

will read as many "double-like" characters as possible and then stop. So, for example, if you entered "2ss" the extractor would consume the "2" and leave the get pointer at the first 's'. If you enter "aa" the extractor consumes nothing. What happens to the extra characters (as well as the newline) is up to you.

Since you didn't consume all the characters in the input buffer, when your loop cycled, one of the remaining characters was consumed by ignore() and you tried again, until they were all gone.

The actual requirement you were trying to implement was either that only a number could be entered on a line (in which case, the suggestion of getline / strod is appropriate), or that all extraneous characters on a line should be silently swallowed, in which case the more precise ignore() specification is correct.

Upvotes: 0

scohe001
scohe001

Reputation: 15446

Instead of cin.ignore();, use:

cin.ignore(std::numberic_limits<std::streamsize>::max(), '\n');

This will ignore either 256 characters, or every character until a newline (whichever comes first). As of now, you only clear one character from the buffer, which--as you've found--isn't always enough.

Thank you to @Arnav and @Dietmar for the proper number of characters to ignore!

Upvotes: 1

Related Questions