Need Help with Getline Problem

I'm working on a program that asks the user for a list of rectangles, I have a function read_rectangles that asks the user for the name of the rectangle. Here's the code for the function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
        bool read_rectangles(const string prompt, const string invalid1, const string invalid2, string & user_input, vector<Rectangle> & Rectangles){

            bool match = false; //boolean variable that checks if name has already been used

            cout << prompt;
            getline(cin, user_input); // I think the issue is here


            if (user_input == "stop") {

                return (true);
            }

            else if (user_input.substr(0,4) != "rec ") {

                cout << invalid1;
                return (false);
            }

            else {
                for (int i = 0; i < Rectangles.size(); i++) {

                    if (user_input == "rec " + Rectangles.at(i).getName()) {

                        match = true;
                    }
                }
                if (match == false) {

                    return true;
                }
                if (match == true) {

                    cout << invalid2;
                    return false;
                }
            }


        }

Now, when I call this function once it behaves correctly as it should, but when it's called a second time, it skips calling the getline and immediately moves on. I have read online about others having the same issue and many have suggesting adding a cin.ignore() of some sort in the code, like so:

1
2
3
4
5
6
     bool read_rectangles(const string prompt, const string invalid1, const string invalid2, string & user_input, vector<Rectangle> & Rectangles){

            cout << prompt;
            cin.ignore();
            getline(cin, user_input);
    ...

OR

1
2
3
4
5
6
     bool read_rectangles(const string prompt, const string invalid1, const string invalid2, string & user_input, vector<Rectangle> & Rectangles){

            cout << prompt;
            getline(cin, user_input);
            cin.ignore();
    ...


However, when I do the first one, it doesn't behave correctly and outputs one of the error messages even though the input is correct, and then when I try the second one and compile the code then the FIRST time (where it would previously work just fine) the function is called, the prompt is displayed and then I enter the correct user input, but then I have to hit enter TWICE for it to take my input.

I hope this makes sense, I don't have much experience with the cin.ignore() in general, and what I have read didn't make a lot of sense for my scenario, so I hope someone can help me out!
Last edited on
I'd say the getline is perfectly fine in its own right, it's only when used in combination with other code which does unformatted input cin >> that there is a problem. Thus the cin.ignore() belongs with that other code (which is not shown on your post).
I believe your third snippet which you say behaves "correctly" does not. Perhaps you meant to put the call to ignore before the call to getline? ;)


On the other hand, if you want getline to never retrieve empty lines,

1
2
3
4
5
    bool read_rectangles(const string prompt, const string invalid1, const string invalid2, string & user_input, vector<Rectangle> & Rectangles){

            cout << prompt;
            getline(cin >> std::ws, user_input);
    ...


which conveniently handles whitespace left in the input stream by formatted input extraction (of which cin >> is, despite Chervil's typo) and also works well if it is not preceded by formatted input extraction.
Last edited on
Topic archived. No new replies allowed.