1

The else statement in this code does not execute, instead, when a character is entered, it would get stuck in a continuous loop, repeating the lines 33 and 35.

I want to check if the user input is not an integer in the else statement and ask the user again to specify the age.

#include <iostream>
#include <windows.h>
using namespace std;

class User {
    string name;
public:
    string getName(){
        return name;
    }
    void setName(string newName) {
        name = newName;
    }
};

int main()
{
    /** Initialise Variables */
    string name;
    int age;
    User u1;
    bool running = true;


    while(running) {
    /** Welcome Message w/ User's Name */
    cout << "What is your name?: " << endl;
    cin >> name;
    u1.setName(name);
    cout << "Welcome, " << u1.getName() << "!" << endl;
    returnToAge:
    Sleep(1000);
    cout << u1.getName() << ", to continue, you have to be over 18." << endl;
    Sleep(1000);
    cout << "Please enter your age: " << endl;
    cin >> age;

        if (age >= 18) {
            cout << "You may continue..." << endl;
            Sleep(1000);
            //Enter rest of questionnaire here   


        }
        else if(age < 18) {
            cout << "You are underage! Please try again!" << endl;
            Sleep(1500);
            goto returnToAge;
        }
        else {
            cout << "INVALID INPUT!" << endl;
            goto returnToAge;
        }
    }

}
LtMuffin
  • 219
  • 2
  • 14
  • You will probably find that not many people like the use of the goto. There tend to be better ways of structuring code so that they're not necessary (they're messy, and hard to control, especially as code grows.) Can I suggest you use a loop around the age entry, and only exit the loop when the conditions are met? Also, might be good to put that sort of operation into a function, as it can be separate from the main flow then, and easier to see/understand. – Rags Nov 12 '18 at 11:29
  • A very general comment: don't use labels and `goto` statements. They are never necessary, and create hard to read code (and bugs as a result of that). – Henning Koehler Nov 12 '18 at 11:30
  • 1
    @Rags I know there are better ways of using something other than goto. It is currently the most understandable code to me, to use at this moment in time. I will use something better as the code grows. I'll have a go with what you have said. – LtMuffin Nov 12 '18 at 11:32
  • @Leon185 I appreciate that can be the most readable - especially in the early stages of a project. It tends to become less so over time! My only point was, you may encounter objections, as some people have a violent objection to GOTO (even though there are - extremely rare - circumstances where they can be the best option.) – Rags Nov 12 '18 at 11:36
  • 2
    A classic in Computer Science history: "goto statements considered harmful" by Edgar Dijkstra https://homepages.cwi.nl/~storm/teaching/reader/Dijkstra68.pdf – Christian G Nov 12 '18 at 11:40
  • 1
    @ChristianG Not only that - there's a lot by Dijkstra that's worth reading. Some of it is quite unpalatable to some people - but his insight was amazing. – Rags Nov 12 '18 at 11:50

3 Answers3

3

You need to check if the input operation succeeded. The easiest way is:

if (cin >> age) {
    // now use age
} else {
    // error
}

Another way which is equivalent:

cin >> age;
if (!cin) {
    // error
}
John Zwinck
  • 239,568
  • 38
  • 324
  • 436
2

The problem is that cin >> age will read an integer into age (as that's the only thing age can store), and no matter what integer that is (it's 0 for non-numbers), it will be either bigger or smaller than 18, hence why your else case is never reached.

To detect invalid input, you need to read in a string and then check whether that string represents a valid integer.

Henning Koehler
  • 2,456
  • 1
  • 16
  • 20
1

Use std::cin::fail to check wether the user input is an integer.

Secondly, avoid maximum practice using gotos, as it produces Spaghetti code structure. You can replace the goto using a while loop as follows:

while (true) 
{
    // code
    std::cin >> age;
    if (!std::cin.fail() && age >= 18) // if cin not failed && the codition
    { 
        /* do something */
        break;   // break the loop!
    }
    else if (!std::cin.fail() && age < 18)  // if cin not failed && the codition
    {  
        /* do something  goto removeed */   
    }
    else { std::cout << "INVALID INPUT!" << std::endl; /* goto removeed */ }
}
JeJo
  • 30,635
  • 6
  • 49
  • 88