0

I'm new to C++ and I'm using Code::Blocks to run my code... The problem is that, I want users to enter an integer value for age, so how do i code to make sure that the program knows if it's an integer or not and loop if it's not an integer? This is the code [][1]

 #include <iostream>
 #include <iomanip>

using namespace std;

int main()
{
    int age;
    string name;

    cout << "Welcome To Maverick Academy! \nWe Are Pleased To Have New Student Around The Globe. \n" << endl;
    cout << "What Is Your Name, Newcomer?\n";
    cin >> name;
    cout << "\nHello, " << name << ". How Old Are You?\n";
    cin >> age;
    do
    {
       cout << "Please Enter Your Age In Numeric. \n";
    } while (cin.fail);

    {
       cin.clear();
    }

    cout << "\nPlease Choose A Class." << endl;

    //printing border
    cout << setfill('-') << setw(1) << "+" << setw(15) << "-" << setw(1) << "+" << setw(15) << "-" << setw(1) << "+" << endl;
    //printing student record
    cout << setfill(' ') << setw(1) << "|" << setw(15) << left << "Classes" << setw(1) << "|" << setw(15) << left << "Advanced" << setw(1) << "|"  << setw(5) << endl;
    //printing border
    cout << setfill('-') << setw(1) << "+" << setw(15) << "-" << setw(1) << "+" << setw(15) << "-" << setw(1) << "+" << endl;
    //printing student record
    cout << setfill(' ') << setw(1) << "|" << setw(15) << left << "Mage" << setw(1) << "|" << setw(15) << left << "Sorceress" << setw(1) << "|"  << setw(5) << endl;
    //printing border
    cout << setfill('-') << setw(1) << "+" << setw(15) << "-" << setw(1) << "+" << setw(15) << "-" << setw(1) << "+" << endl;
    //printing student record`enter code here`
    cout << setfill(' ') << setw(1) << "|" << setw(15) << left << "Fighter" << setw(1) << "|" << setw(15) << left << "Warrior" << setw(1) << "|" << endl;
    //printing border
    cout << setfill('-') << setw(1) << "+" << setw(15) << "-" << setw(1) << "+" << setw(15) << "-" << setw(1) << "+" << endl;
    //printing student record
    cout << setfill(' ') << setw(1) << "|" << setw(15) << left << "Ninja" << setw(1) << "|" << setw(15) << left << "Assassin" << setw(1) << "|"  << setw(5) << endl;
    //printing border
    cout << setfill('-') << setw(1) << "+" << setw(15) << "-" << setw(1) << "+" << setw(15) << "-" << setw(1) << "+" << endl;

    return 0;

}
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
AJ Tech
  • 13
  • 5

1 Answers1

1

I'm pretty sure the problem is in your do while loop.

int age;
do {
    if(cin.fail()){
        cin.clear();
        cin.ignore(numeric_limits<streamsize>::max(), '\n');
    }    
    cout << "Please Enter Your Age In Numeric. \n";
    cin >> age;
} while(cin.fail());

Should work. It runs the loop at least once (do) and keeps repeating (clearing cin and prompting the user for input), until cin.fail() is false, at which point you know the input was valid.

Just for clarification, cin.fail() returns true if the input was invalid (e.g., input doesn't fit the variable type), and so the stream is broken (which is why calling cin.clear() is important).

It's also worth noting that you need parentheses after cin.fail, given that it's a method call. This might be able to give you some more insight on how cin, cin.fail() and cin.clear() work.

Community
  • 1
  • 1
osuka_
  • 484
  • 5
  • 15
  • @Galik I haven't done C++ in a while, but that looks fine to me. `do` runs the loop at least once, `cin.clear()` resets `cin` to a "good" state, then `cout` and `cin` prompt the user for input. If `cin >> age;` fails (in which case the input is invalid), `cin.fail()` is true, so that it'll keep running until the user inputs an int. `cin.fail()` returns false if `cin` is in a good state, and `cin.clear()` ensures that that's the case for every loop iteration. – osuka_ Nov 14 '15 at 18:36
  • I tried that one, but as @Galik said, it runs an infinite loop, is there any way to ensure that the code loop once ? – AJ Tech Nov 14 '15 at 18:49
  • @AJTech Okay, fixed it. Sorry it took me a while - something came up and I had to take care of it. Let's go through the code: `do` ensures the loop runs at least once; the if statement ensures that, if the input was invalid, `cin` is returned to a good state and that it's "empty" (so that the invalid input isn't used again). `cin.sync()` synchronizes the input stream after it's set to a good state, so that `cin.ignore()` works properly. – osuka_ Nov 14 '15 at 19:16
  • Thanks @osuka_ i tried both of the code and the results are the same, since im new, and still wondering about the cin,sync() yet (maybe it will be used in future / advanced project), im going with the code given by Galik as it's easier – AJ Tech Nov 14 '15 at 19:31
  • Okay, now I'm confused. I just ran it and it worked. But hey, go with the solution that you like the best - if you don't feel comfortable using `cin.sync()`, that's completely fine. Again, I'm sorry for the screwups, and glad that you could make it work! I'll just leave the answer there (and I suggest you keep the question too!), so that in case you or anyone else needs it, it's available. Good luck with the remainder of your project! – osuka_ Nov 14 '15 at 19:35