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