Getline продолжает получать символ новой строки. Как мне этого избежать?

В основном я сначала принимает целое число в качестве входных данных, а затем следует тестовый случай. Каждый мой тест-это строка. Я должен распечатать строку обратно, если начальный Паттен строки соответствует "HI A", и он нечувствителен к регистру. Я написал код ниже, чтобы выполнить это. Моя проблема в том, что когда я нажимаю enter после каждого ввода, getline принимает символ новой строки в качестве нового ввода. Я попытался решить эту проблему, используя дополнительную getline после каждого ввода, но проблема все еще существует. Программа застревает петля, хотя я поставил условие перерыва. Что я делаю не так?

#include <iostream>
#include <string>
using namespace std;
int main(){
    int N;
    cin >>N;
    string nl;
    getline(cin,nl);
    for (int i=0;i<N;i++){
        string s;
        getline(cin,s);
        //cout <<"string"<<s<<endl;
        int flag=0;
        if ((s.at(0)=='h'||s.at(0)=='H')&&(s.at(1)=='i'||s.at(1)=='I')&&(s.at(2)==' ')&&(s.at(3)=='a'||s.at(3)=='A')) flag=1;

        if (flag==1) cout << s;
        //cout << "not " <<s;
        string ne;
        cout << "i="<< i<<endl;
        if (i==N-1) {break;}
        getline(cin,ne);

    }
}

вот пример ввода:

5
Hi Alex how are you doing
hI dave how are you doing
Good by Alex
hidden agenda
Alex greeted Martha by saying Hi Martha

вывод должен быть:

Hi Alex how are you doing

4 ответов


код cin >>N останавливается на первом нечисловом символе, который является новой строкой. Это у вас есть getline читать мимо него, это хорошо.

каждый дополнительный getline после этого читает всю строку,включая новую строку в конце. Положив в секунду getline вы пропускаете половину ввода.


функция ignore () делает трюк. По умолчанию он отбрасывает все входные suquences до Нового символа строки.

другие дилимитеры и предел char можно определить также.

http://www.cplusplus.com/reference/istream/istream/ignore/

в вашем случае это происходит так.

    cin >> N;
    cin.ignore();

Итак, ваша настоящая проблема не в этом getline ест newlines, но это ваш второй getline(cin, ne) ест линию...

и это потому, что вы ошибочно думаете, что вам нужно два getline операции для чтения одной строки-или что-то в этом роде. Смешивание ввода" linebased "и" itembased "имеет запутанные способы борьбы с новыми строками, поэтому вам нужно что-то" пропустить " новую строку, оставленную позади frin cin >> N;, но как только вы избавитесь от этого, вам понадобится только один getline читать и включая новую строку в конце строки.


вам просто нужно принять тот факт, что getline даст вам '\n' в конце. Одним из решений является удаление '\n ' после его получения. Другое решение - не писать дополнительный "endl". например, для вашей проблемы, вы можете использовать этот код

int N;
cin >> N;
string line;
getline(cin, line); // skip the first new line after N.
for (int i = 0; i < N; i++) {
  string line;
  getline(cin, line);
  string first4 = line.substr(0, 4);
  // convert to upper case.
  std::transform(first4.begin(), first4.end(), first4.begin(), std::ptr_fun<int, int>(std::toupper)); // see http://en.cppreference.com/w/cpp/algorithm/transform
  if (first4 == "HI A") {
    cout << line;  // do not include "<< endl"
  }
}