Thanks in advance for your help. I am writing a program that is supposed to display a menu and ask the user to enter a list of his/her favorite games, then display the games if they choose to. The problem is that when it comes to entering the names of the games, it automatically enters a null value in the first element of the vector. I've tried to put a cin.ignore(), but if the string contains a space and a number at the end, the program will interpret that number as something else and spit out the error for inputting the menu choices. Here is my code:

#include <iostream>
#include <string>
#include <vector>

using namespace std;
vector<string> list;

int main()
{
    int num;  
    int fav;
    string g;
    
    char ag;
    
    //display menu    
    cout << "Welcome to Your Favorite Games List Generator." << endl;
    cout << "Here is the Menu:" << endl << endl;
    cout << "1) Enter games into your list." << endl;
    cout << "2) Display your list." << endl;
    cout << "3) Quit." << endl;
    cout << endl;
    cout << "What would you like to do?" << endl;
    cin >> num;  //get user's input from menu choices
    cout << endl; 
    
    while(1)
    {
        if(cin.fail())  //validate user input
        {
            cin.clear();
            cin.ignore(100, '\n');
            cout << "I'm sorry. You can only enter numbers 1-3 here." << endl;
            cout << "\nWhat would you like to do?" << endl;
            cin >> num;
            continue;
        }
        break;
    }    
    
    switch(num)
    {
        case 1: cout << "Great. How many favorite games do you have?" << endl;
                cin >> fav;  //get number of favorite games
                cout << endl;
                
                cout << "Would you like to enter your games?" << endl;
                cin >> ag; //establish condition for loop               
                
                do
                {
                    for(int x = 0; x < fav; x++)
                    {
                        cout << "Enter game: \n";
                        getline(cin, g); //get names of games
                        
                        list.push_back(g); //store names in a vector                     
                    }
                    
                    cout << "Would you like to enter another game?" << endl;
                    cin >> ag; // ask if user is done
                    
                }while(ag == 'y' || ag == 'Y'); //end loop
                
                if(ag != 'y' || ag != 'Y') //if user is done, return to the menu
                {
                    cout << "\n\nOk. Thanks for entering your games." << endl;
                    cout << endl;
                    main();
                }        
                break;
        case 2: if(list.empty()) //check for an empty vector
                {
                    cout << "I'm sorry. You can't display a list that hasn't" << endl;
                    cout << "been created yet. Choose either #1 or #3." << endl;
                    cout << endl;
                    main();
                }
                for(int i = 0; i < list.size(); i++) //display list of names
                {
                    cout << list[i];
                    cout << endl;
                }
                break;
        case 3: exit(0);    //exit the program                                        
                    
    }
    
    system("pause");
    return (0);
}

Recommended Answers

All 11 Replies

Whenever you use a getline right after using a >> operator, problems have the potential to occur if you don't clear the input stream. You say you used ignore, but I don't see where you used it (except when you test for cin.fail ()), so I can't comment. Narue has a post pinned to the top of the C++ forum that you should look at it. It's not a null, it's an empty string because the '\n' is left over from >>, then getline grabs it and thinks it's done.

If you ever use getline or get immediately after the >> operator, vlear the input screen (again, see Narue's pinned thread) and see if that makes a difference.

Whenever you use a getline right after using a >> operator, problems have the potential to occur if you don't clear the input stream. You say you used ignore, but I don't see where you used it (except when you test for cin.fail ()), so I can't comment. Narue has a post pinned to the top of the C++ forum that you should look at it. It's not a null, it's an empty string because the '\n' is left over from >>, then getline grabs it and thinks it's done.

If you ever use getline or get immediately after the >> operator, vlear the input screen (again, see Narue's pinned thread) and see if that makes a difference.

Ok...I'll check it out. Thanks. I had the ignore in, but I took it out because it was causing problems as well.

Despite numerous attempts at resolving my issue with Narue's instructions (both basic and advanced), my problem still remains in that the first character is deleted. My output would look something like this:

COD
OD 2
OD 3
OD 4

Any other suggestions?

Despite numerous attempts at resolving my issue with Narue's instructions (both basic and advanced), my problem still remains in that the first character is deleted. My output would look something like this:

COD
OD 2
OD 3
OD 4

Any other suggestions?

I don't know what you did, but when I copy line 32 to lines 49 and 62, I don't have that problem.

Without the ignore, I get the initial problem of having an empty string. With the ignore, I get the problem of having the first letters cut off. I know it's probably something minor that I'm overlooking...I just can't seem to get it figured out.

Without the ignore, I get the initial problem of having an empty string. With the ignore, I get the problem of having the first letters cut off. I know it's probably something minor that I'm overlooking...I just can't seem to get it figured out.

Post the updated code, post the exact input, and post the exact output for that input so we can try it out for ourselves.

Ok...here is the code..same as the one that is posted, only with some extra preprocessor directives I was using while trying Narue's clearing input methods:

#include <iostream>
#include <string>
#include <vector>
#include <istream>
#include <ios>
#include <limits>

using namespace std;
vector<string> list;

int main()
{
    int num;  
    int fav;
    string g;
    
    char ag;
    
    //display menu    
    cout << "Welcome to Your Favorite Games List Generator." << endl;
    cout << "Here is the Menu:" << endl << endl;
    cout << "1) Enter games into your list." << endl;
    cout << "2) Display your list." << endl;
    cout << "3) Quit." << endl;
    cout << endl;
    cout << "What would you like to do?" << endl;
    cin >> num;  //get user's input from menu choices
    cout << endl; 
    
    while(1)
    {
        if(cin.fail())  //validate user input
        {
            cin.clear();
            cin.ignore(100, '\n');
            cout << "I'm sorry. You can only enter numbers 1-3 here." << endl;
            cout << "\nWhat would you like to do?" << endl;
            cin >> num;
            continue;
        }
        break;
    }    
    
    switch(num)
    {
        case 1: cout << "Great. How many favorite games do you have?" << endl;
                cin >> fav;  //get number of favorite games
                cout << endl;
                
                cout << "Would you like to enter your games?" << endl;
                cin >> ag; //establish condition for loop               
                cout << endl;
                
                do
                {
                    for(int x = 0; x < fav; x++)
                    {
                        cout << "Enter game: \n" << endl;                                                           
                        getline(cin, g); //get names of games
                        
                        
                        list.push_back(g); //store names in a vector                     
                    }
                    
                    cout << "Would you like to enter another game?" << endl;
                    cin >> ag; // ask if user is done
                    
                }while(ag == 'y' || ag == 'Y'); //end loop
                
                if(ag != 'y' || ag != 'Y') //if user is done, return to the menu
                {
                    cout << "\n\nOk. Thanks for entering your games." << endl;
                    cout << endl;
                    main();
                }        
                break;
        case 2: if(list.empty()) //check for an empty vector
                {
                    cout << "I'm sorry. You can't display a list that hasn't" << endl;
                    cout << "been created yet. Choose either #1 or #3." << endl;
                    cout << endl;
                    main();
                }
                for(int i = 0; i < list.size(); i++) //display list of names
                {
                    cout << list[i];
                    cout << endl;
                }
                break;
        case 3: exit(0);    //exit the program                                        
                    
    }
    
    system("pause");
    return (0);
}

The i/o for this is:

INPUT:
1 - To enter names for the list.
4 - Number of favorite games
y - Would you like to enter your games

OUTPUT:
Enter game:

Enter game:
(This is where the program allows you to enter the second name, the first is already empty)

Here it is with the ignore included:

#include <iostream>
#include <string>
#include <vector>
#include <istream>
#include <ios>
#include <limits>

using namespace std;
vector<string> list;

int main()
{
    int num;  
    int fav;
    string g;
    
    char ag;
    
    //display menu    
    cout << "Welcome to Your Favorite Games List Generator." << endl;
    cout << "Here is the Menu:" << endl << endl;
    cout << "1) Enter games into your list." << endl;
    cout << "2) Display your list." << endl;
    cout << "3) Quit." << endl;
    cout << endl;
    cout << "What would you like to do?" << endl;
    cin >> num;  //get user's input from menu choices
    cout << endl; 
    
    while(1)
    {
        if(cin.fail())  //validate user input
        {
            cin.clear();
            cin.ignore(100, '\n');
            cout << "I'm sorry. You can only enter numbers 1-3 here." << endl;
            cout << "\nWhat would you like to do?" << endl;
            cin >> num;
            continue;
        }
        break;
    }    
    
    switch(num)
    {
        case 1: cout << "Great. How many favorite games do you have?" << endl;
                cin >> fav;  //get number of favorite games
                cout << endl;
                
                cout << "Would you like to enter your games?" << endl;
                cin >> ag; //establish condition for loop               
                cout << endl;
                
                do
                {
                    for(int x = 0; x < fav; x++)
                    {
                        cout << "Enter game: \n" << endl;  
                        cin.ignore();                                                         
                        getline(cin, g); //get names of games
                        
                        
                        list.push_back(g); //store names in a vector                     
                    }
                    
                    cout << "Would you like to enter another game?" << endl;
                    cin >> ag; // ask if user is done
                    
                }while(ag == 'y' || ag == 'Y'); //end loop
                
                if(ag != 'y' || ag != 'Y') //if user is done, return to the menu
                {
                    cout << "\n\nOk. Thanks for entering your games." << endl;
                    cout << endl;
                    main();
                }        
                break;
        case 2: if(list.empty()) //check for an empty vector
                {
                    cout << "I'm sorry. You can't display a list that hasn't" << endl;
                    cout << "been created yet. Choose either #1 or #3." << endl;
                    cout << endl;
                    main();
                }
                for(int i = 0; i < list.size(); i++) //display list of names
                {
                    cout << list[i];
                    cout << endl;
                }
                break;
        case 3: exit(0);    //exit the program                                        
                    
    }
    
    system("pause");
    return (0);
}

INPUT:
1 - Enter list
4 - Number of games
y - Enter games

Enter game:
COD

Enter game:
COD 2

Enter game:
COD 3

Enter game:
COD 4

Would you like to enter another game?
n

(this brings you back to the main menu)

2 - Display list of games

OUTPUT:
COD
OD 2
OD 3
OD 4

Stick them after you use the >> operator and before get or getline, and specify the '\n'. Try below.

#include <iostream>
#include <string>
#include <vector>
#include <istream>
#include <ios>
#include <limits>

using namespace std;
vector<string> list;

int main()
{
    int num;
    int fav;
    string g;

    char ag;

    //display menu
    cout << "Welcome to Your Favorite Games List Generator." << endl;
    cout << "Here is the Menu:" << endl << endl;
    cout << "1) Enter games into your list." << endl;
    cout << "2) Display your list." << endl;
    cout << "3) Quit." << endl;
    cout << endl;
    cout << "What would you like to do?" << endl;
    cin >> num;  //get user's input from menu choices
    cout << endl;

    while(1)
    {
        if(cin.fail())  //validate user input
        {
            cin.clear();
            cin.ignore(100, '\n');
            cout << "I'm sorry. You can only enter numbers 1-3 here." << endl;
            cout << "\nWhat would you like to do?" << endl;
            cin >> num;
            continue;
        }
        break;
    }

    switch(num)
    {
        case 1: cout << "Great. How many favorite games do you have?" << endl;
                cin >> fav;  //get number of favorite games
                cout << endl;

                cout << "Would you like to enter your games?" << endl;
                cin >> ag; //establish condition for loop
                cout << endl;
                cin.ignore(100, '\n');

                do
                {
                    for(int x = 0; x < fav; x++)
                    {
                        cout << "Enter game: \n" << endl;
                        getline(cin, g); //get names of games


                        list.push_back(g); //store names in a vector
                    }

                    cout << "Would you like to enter another game?" << endl;
                    cin >> ag; // ask if user is done
                    cin.ignore(100, '\n');

                }while(ag == 'y' || ag == 'Y'); //end loop

                if(ag != 'y' || ag != 'Y') //if user is done, return to the menu
                {
                    cout << "\n\nOk. Thanks for entering your games." << endl;
                    cout << endl;
                    main();
                }
                break;
        case 2: if(list.empty()) //check for an empty vector
                {
                    cout << "I'm sorry. You can't display a list that hasn't" << endl;
                    cout << "been created yet. Choose either #1 or #3." << endl;
                    cout << endl;
                    main();
                }
                for(int i = 0; i < list.size(); i++) //display list of names
                {
                    cout << list[i];
                    cout << endl;
                }
                break;
        case 3: exit(0);    //exit the program

    }

    system("pause");
    return (0);
}

YES!!! That's it. It works. I had a feeling it was something minor. Was it because I had it inside the for loop, and not towards the end of the do while loop, causing it to ignore every time it looped? Either way, thanks a lot. This was driving me crazy. I've been pulling my hair out since last Thursday. :-)

YES!!! That's it. It works. I had a feeling it was something minor. Was it because I had it inside the for loop, and not towards the end of the do while loop, causing it to ignore every time it looped? Either way, thanks a lot. This was driving me crazy. I've been pulling my hair out since last Thursday. :-)

You're welcome.

If you have two getlines in a row and you stick an "ignore" in between, you lose data because there is nothing to ignore and by telling the program to ignore something, it ignores that first character, so don't put an ignore statement BETWEEN two getline statements whether they are in a loop or not.

Putting an ignore statement BEFORE a statement using >> won't have an effect in your case because the >> will ignore the white space anyway (there's no harm done and no benefit).

If you ask the user for input, expecting the user to type something, then hit return, the >> operator will leave that last '\n' character in the input stream and if you use a getline immediately after, getline will grab it. That's why you use the ignore statement and that's why you specify that you want to throw away the rest of the line (100 is just a big number that will eat up any spaces, tabs, whatever, that the user might type after the actual data), up to and including the '\n', and start fresh with the next line.

So the general rule of thumb is (there are exceptions, depending on your needs):

  1. Use cin.ignore (100, '\n') immediately after reading in data using the >> operator if you want to throw away the rest of that line and start with an empty input buffer for the next line.
  2. Don't use ignore between two getline statements.
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.