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

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?

Answers


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;

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();

just write

cin.ignore();

after your last ">>" operator. ">>" operator leaves a newline "\n" in the input bitstream which needs to be cleared before taking the inputs.


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


Need Your Help

How to select items from two lists where the ids don't match

c# linq

Ok, so I have two lists of items which are of different types.

How to present a modal view controller on the iphone without a "current" view controller?

iphone uiview uiviewcontroller mfmailcomposeviewcontroller

I'm trying to open the email view controller (MFMailComposeViewController), and everything I read suggests using presentModalViewController:animated:, which seems to need to be sent to a UIViewCont...