cin.getline() is skipping an input in C++

25,058

Solution 1

This:

cin>>n;

Is reading the number only.
It leaves the trailing '\n' on the stream.

So your first call to getline() is reading an empty line containing just a '\n'

It is best not to mix the use of operator>> and std::getline(). You have to be very careful on whether you have left the newline on the stream. I find it easiest to always read a line at a time from a user. Then parse the line separately.

 std::string  numnber;
 std::getline(std::cin, number);

 int n;
 std::stringstream numberline(number);
 numberline >> n;

Solution 2

your cin.ignore() is in the wrong place. getline does not leave the trailing \n newline character, it's the >> symbol which does that.

What you probably want is

cin>>n;
cin.ignore();

Solution 3

actually the cin buffer has \n remaining from last cin, so getline take this \n character and gets terminated; ignore the content of buffer before getline...

cin.ignore();

getling(cin, string_name);

//it will work smoothly

Share:
25,058
theharshest
Author by

theharshest

Machine Learning and Data Mining enthusiast. Interested in Python, C++, Data Structures and Algorithms. Metalhead! SOreadytohelp

Updated on July 18, 2022

Comments

  • theharshest
    theharshest almost 2 years

    If I use the following code, getline doesn't take the last input(for last iteration of "for" loop, it simply skips it) -

    int main()
    {
        int n;
        map<string, set<string> > lst;
        string c,s,c2;
    
        cin>>n;
    
        for(int i=0;i<n;i++)
        {
                getline(cin,c); // here it skips the input for last iteration
                stringstream ss;
                ss<<c;
    
                bool f=1;
                while(ss>>s)
                {
                            if(f)
                            {
                                 c2=s;
                                 f=0;
                            }
                            else
                                 lst[c2].insert(s);           
                }
        }
    
        for (map<string, set<string> >::const_iterator ci = lst.begin(); ci != lst.end(); ++ci)
        {
                    cout<< (*ci).first <<" "<< (*ci).second.size() <<endl;
        }
    }
    

    To get rid of it, I put cin.ignore() after getline. Now its taking all the inputs but I'm facing a new issue -

    #include<iostream>
    #include<string>
    #include<map>
    #include<set>
    #include<sstream>
    #include<algorithm>
    
    using namespace std;
    
    int main()
    {
        int n;
        map<string, set<string> > lst;
        string c,s,c2;
    
        cin>>n;
    
        for(int i=0;i<n;i++)
        {
                getline(cin,c);
                cin.ignore();
                stringstream ss;
                ss<<c;
    
                bool f=1;
                while(ss>>s)
                {
                            if(f)
                            {
                                 c2=s;
                                 f=0;
                            }
                            else
                                 lst[c2].insert(s);           
                }
        }
    
        for (map<string, set<string> >::const_iterator ci = lst.begin(); ci != lst.end(); ++ci)
        {
                    cout<< (*ci).first <<" "<< (*ci).second.size() <<endl;
        }
    }
    

    The new issue is that while taking c2, first character of string gets removed. For example, if I give "England Jane Doe" as input to getline, in c2 I'll get "ngland".

    How to get rid of this issue now?

  • alexisdm
    alexisdm about 12 years
    cin.ignore only ignores 1 character, you need to ignore all characters until the \n newline character.
  • theharshest
    theharshest about 12 years
    Thanks for the nice explanation! :)