Need Help with Getline Problem

Apr 18, 2016 at 11:33pm
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 Apr 18, 2016 at 11:39pm
Apr 19, 2016 at 3:15am
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).
Apr 19, 2016 at 3:26am
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 Apr 19, 2016 at 3:27am
Topic archived. No new replies allowed.