cin.getline() пропускает ввод в C++

Если я использую следующий код, getline не принимает последний ввод (для последней итерации цикла «for» он просто пропускает его) -

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;
    }
}

Чтобы избавиться от этого, я поставил cin.ignore() после getline. Теперь он принимает все входные данные, но я столкнулся с новой проблемой -

#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;
    }
}

Новая проблема заключается в том, что при выборе c2 удаляется первый символ строки. Например, если я введу «England Jane Doe» в качестве входных данных для getline, в c2 я получу «ngland».

Как теперь избавиться от этой проблемы?


person theharshest    schedule 17.04.2012    source источник
comment
Смешивание >> и getline деликатно. В любом случае, вы никогда не проверяете результат ни того, ни другого, так почему вы вообще ожидаете, что ваш код будет работать?   -  person Kerrek SB    schedule 18.04.2012
comment
(*ci).first легче читать как ci->first   -  person Martin York    schedule 18.04.2012


Ответы (4)


Этот:

cin>>n;

Читает только число.
В потоке остается конечный '\n'.

Таким образом, ваш первый вызов getline() читает пустую строку, содержащую только '\n'

Лучше не смешивать использование operator>> и std::getline(). Вы должны быть очень осторожны, не оставили ли вы новую строку в потоке. Я считаю, что проще всего всегда читать строку за раз от пользователя. Затем разберите строку отдельно.

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

 int n;
 std::stringstream numberline(number);
 numberline >> n;
person Martin York    schedule 17.04.2012
comment
Спасибо за хорошее объяснение! :) - person theharshest; 18.04.2012

ваш cin.ignore() находится не в том месте. getline не оставляет завершающий символ новой строки \n, это делает символ >>.

То, что вы, вероятно, хотите, это

cin>>n;
cin.ignore();
person Ben Cottrell    schedule 17.04.2012
comment
cin.ignore игнорирует только 1 символ, вам нужно игнорировать все символы до символа новой строки \n. - person alexisdm; 18.04.2012

на самом деле в буфере cin осталось \n от последнего cin, поэтому getline берет этот символ \n и завершается; игнорировать содержимое буфера перед getline...

cin.игнорировать();

получение (cin, имя_строки);

//будет работать гладко

person Rajeev    schedule 02.11.2014

просто пиши

cin.ignore();

после вашего последнего оператора ">>". Оператор «>>» оставляет новую строку «\n» во входном потоке битов, которую необходимо очистить перед вводом данных.

person Vikas Kalwani    schedule 22.06.2014