0

I am having a number of problems in my program that all have to do with input. The first thing in the program I ask the user to input is their name which I do so with this

cout << "Please tell me your name." << endl;
getline(cin, user_name);
cout << "Hello " << user_name << " and welcome to Fantasy Battle!" << endl;

where user_name is declared as a string variable elsewhere. This part seems to have no problems as the following message displays to the screen correctly

The next input from the user comes from this code

{
cout << "Hello, what would you like to do?" << endl;
cout << "1. Play" << endl << "2. Exit" << endl;
cout << "Please enter the number corresponding to your choice from the list 
above." << endl;
for(;;)
{
    if(cin >> menuChoice)
    {
        if(cin.get() == '.')
        {
            cin.clear();
            cin.ignore(10000, '\n');
        }
        if(menuChoice == 1 || menuChoice == 2)
            break;
        else
        {
            cout << "You did not enter a valid menu option. Please try 
            again." << endl;
            cin.clear();
            cin.ignore(100000, '\n');
        }
    }
    else
    {
        cout << "You did not enter a valid menu option. Please try again." 
        << endl;
        cin.clear();
        cin.ignore(100000, '\n');
    }
}
if(menuChoice == 2)
{
    return 2;
}
else
{
    //setup a fight code further down
}

One the first run through if I enter 2 it will exit the program successfully from main or if enter 1 it will run through the fight function. However, if I go through 1 fight and get back the program asking me to either enter 1 or 2 to play or exit, I can enter 2 infinite times and it will not exit the program. I am not sure what it causing this.

for(;;)
    {
        game = menu();
        if(game == 2)
        {
            break;
        }
        else
        {
            fight();
        }
     }
     return 0;

The code inside the menu() function of my program is as follows and is where the rest of the input for my program is contained. I am using getline(cin, fighterName) to get a string from the user to use as a name for each character they want to create The problem I am having is that it starts to just save the name of characters as empty without asking.

cout << "How many fighters should be on Team 1?" << endl;
//Input Validation
for(;;)
{
    if(cin.get() == '.')
    {
        cin.clear();
        cin.ignore(100000, '\n');
    }
    if(cin >> team1Size)
    {
        if(team1Size <= 0)
        {
            cout << "The team must be a size of at least 1 fighter. Please try again." << endl;
            cin.clear();
            cin.ignore(100000, '\n');
        }
        else
        {
            break;
        }
    }
    else
    {
        cout << "You did not enter a valid number. Please try again." << endl;
           cin.clear();
            cin.ignore(100000, '\n');
    }
}

cout << "How many fighters should be on Team 2?" << endl;
//Input Validation
for(;;)
{
    if(cin.get() == '.')
    {
        cin.clear();
        cin.ignore(100000, '\n');
    }
    if(cin >> team2Size)
    {
        if(team2Size <= 0)
        {
            cout << "The team must be a size of at least 1 fighter. Please try again." << endl;
            cin.clear();
            cin.ignore(100000, '\n');
        }
        else
        {
            break;
        }
    }
    else
    {
        cout << "You did not enter a valid number. Please try again." << endl;
           cin.clear();
            cin.ignore(100000, '\n');
    }
}

//Set up team 1 
cout << "Begin setup for team 1:" << endl << endl;
for(int i = 0; i < team1Size; i++)
{
    cout << "Which character type should fighter " << i+1 << " be?" << endl;
    cout << "1. Barbarian" << endl;
    cout << "2. BlueMen" << endl;
    cout << "3. Vampire" << endl;
    cout << "4. Medusa" << endl;    
    cout << "5. Harry Potter" << endl;
    cout << "Please enter the number corresponding to your choice from the list above." << endl;
    for(;;)
    {
        if(cin.get() == '.')
        {
            cin.clear();
            cin.ignore(100000, '\n');
        }
        if(cin >> fighterType)
        {
            if(fighterType < 1 || fighterType > 5)
            {
                cout << "You did not enter a valid choice. Please try again." << endl;
                cin.clear();
                cin.ignore(100000, '\n');
            }
            else
                break;
        }
        else
        {
            cout << "You did not enter a valid choice. Please try again." << endl;
            cin.clear();
            cin.ignore(100000, '\n');
        }
    }
    //Now that we have the desired type of the fighter we must add a fighter of the correct type to the linked list
    //representing team 1. We will do so by calling the add function of the linked list
    cout << "Please enter the name of this fighter." << endl;
    getline(cin, fighterName);
    if(fighterType == 1)
    {
        team1.addBack("Barbarian", fighterName);
    }
    else if(fighterType == 2)
    {
        team1.addBack("BlueMen", fighterName);
    }
    else if(fighterType == 3)
    {
        team1.addBack("Vampire", fighterName);
    }
    else if(fighterType == 4)
    {
        team1.addBack("Medusa", fighterName);
    }
    else
    {
        team1.addBack("HarryPotter", fighterName);
    }

}

cout << "Team 1 has been created!" << endl << endl;

//Set up team 2 
cout << "Begin setup for team 2:" << endl << endl;
for(int i = 0; i < team2Size; i++)
{
    cout << "Which character type should fighter " << i+1 << " be?" << endl;
    cout << "1. Barbarian" << endl;
    cout << "2. BlueMen" << endl;
    cout << "3. Vampire" << endl;
    cout << "4. Medusa" << endl;    
    cout << "5. Harry Potter" << endl;
    cout << "Please enter the number corresponding to your choice from the list above." << endl;
    for(;;)
    {
        if(cin.get() == '.')
        {
            cin.clear();
            cin.ignore(100000, '\n');
        }
        if(cin >> fighterType)
        {
            if(fighterType < 1 || fighterType > 5)
            {
                cout << "You did not enter a valid choice. Please try again." << endl;
                cin.clear();
                cin.ignore(100000, '\n');
            }
            else
                break;
        }
        else
        {
            cout << "You did not enter a valid choice. Please try again." << endl;
            cin.clear();
            cin.ignore(100000, '\n');
        }
    }
    //Now that we have the desired type of the fighter we must add a fighter of the correct type to the linked list
    //representing team 2. We will do so by calling the add function of the linked list
    cout << "Please enter the name of this fighter." << endl;
    getline(cin, fighterName);
    if(fighterType == 1)
    {
        team2.addBack("Barbarian", fighterName);
    }
    else if(fighterType == 2)
    {
        team2.addBack("BlueMen", fighterName);
    }
    else if(fighterType == 3)
    {
        team2.addBack("Vampire", fighterName);
    }
    else if(fighterType == 4)
    {
        team2.addBack("Medusa", fighterName);
    }
    else
    {
        team2.addBack("HarryPotter", fighterName);
    }
}


cout << "Team 2 has been created!" << endl << endl;

cout << "Let the fight begin!" << endl << endl;

return 0;

}

The final piece of input from my code is the following which simply asks the user to enter a character either y or n and then executes a function if y is entered.

cout << "Would you like to see the contents of the loserPile?" << endl;
    cout << "Please enter y for yes or n for no" << endl;
    for(;;)
    {
        if(cin >> displayLosers)
        {
            if(displayLosers != 'y' && displayLosers != 'n')
            {
                cout << "You did not enter either y or n. Please try again." << endl;
                cin.clear();
                cin.ignore(100000, '\n');
            }
            else
                break;
        }
        else
        {
            cout << "You did not enter either y or n. Please try again." << endl;
            cin.clear();
            cin.ignore(100000, '\n');
        }
    }
    if(displayLosers == 'y')
    {
        losers.displayPile();
    }

If someone could point out where I am making the error in obtaining user input I would appreciate it as I am running out of things to try that I know of.

  • Far too much code. Please provide a [mcve]. Something like 5 lines of code should be sufficient to demonstrate a problem with `getline` – 463035818_is_not_a_number Nov 15 '17 at 19:13
  • Possible duplicate of [Why does std::getline() skip input after a formatted extraction?](https://stackoverflow.com/questions/21567291/why-does-stdgetline-skip-input-after-a-formatted-extraction) – user0042 Nov 15 '17 at 19:27
  • What are the type(s) of your string variables? Are they character arrays or `std::string` or some other data type? – Thomas Matthews Nov 15 '17 at 21:12

1 Answers1

0

You are creating a lot of problems by adding if(cin.get() == '.')

The >> operator will convert the input string "1." to 1, and if you call ignore(...,'\n') the . and any other characters before \n will be ignored. Test for if(cin >> number){...} is also not necessary. You can initialize the value to -1 to indicate an error:

int menuChoice;
for(;;)
{
    menuChoice = -1;
    cin >> menuChoice;
    cout << menuChoice;
    cin.clear();
    cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    if(menuChoice == 1 || menuChoice == 2)
    {
        cout << menuChoice << "\n";
        break;
    }
    cout << "You did not enter a valid menu option. Please try again." << endl;
}

Just make sure you are using the right input. For Yes or No option the input should be char:

cout << "enter y or n\n";
for(;;)
{
    char val;
    cin >> val;
    if(val != 'y' && val != 'n')
    {
        cout << "You did not enter either y or n. Please try again." << endl;
        cin.clear();
        cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    }
    else
        break;
}
Barmak Shemirani
  • 26,741
  • 4
  • 33
  • 61
  • The majority of my problems were with cin,get() as you said especially with where I had it located in the validation code. – Shane Leavens Nov 15 '17 at 23:02