6

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?

theharshest
  • 7,219
  • 9
  • 35
  • 50

4 Answers4

16

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;
phadej
  • 11,537
  • 36
  • 72
Martin York
  • 234,851
  • 74
  • 306
  • 532
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();
Ben Cottrell
  • 4,680
  • 1
  • 23
  • 31
  • 1
    `cin.ignore` only ignores 1 character, you need to ignore all characters until the `\n` newline character. – alexisdm Apr 17 '12 at 23:04
1

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

Rajeev
  • 21
  • 2
0

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.