Getline keeps on getting newline character. How can I avoid this?

谁说胖子不能爱 提交于 2019-11-27 15:11:34

问题


Basically I first takes an integer as input and then test case follows. My each test case is an string. I am suppose to print the string back if the starting patten of string matches "HI A" and it is case-insensitive. I wrote the code below to accomplish to this. My problem is that when I press enter after each input, getline takes newline character as new input. I have tried to tackle this by using extra getline after each input but the issue is still there. Program gets stuck in the loop even though I have put a break condition. What am I doing wrong?

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

    }
}

Here is sample input:

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

Output should be:

Hi Alex how are you doing

回答1:


Your cin >>N stops at the first non-numeric character, which is the newline. This you have a getline to read past it, that's good.

Each additional getline after that reads the entire line, including the newline at the end. By putting in a second getline you're skipping half your input.




回答2:


ignore() function does the trick. By default, it discards all the input suquences till new line character.

Other dilimiters and char limit can be specified as well.

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

In your case it goes like this.

    cin >> N;
    cin.ignore();



回答3:


So, your real problem isn't that getline eats newlines, but that your second getline(cin, ne) is eating a line...

And that is because you mistakenly think that you need two getline operations to read one line - or something like that. Mixing "linebased" and "itembased" input does have confusing ways to deal with newlines, so you do need something to "skip" the newline left behind frin cin >> N;, but once you have got rid of that, you only need ONE getline to read up and including the newline at the end of a line.




回答4:


you just need to accept the fact that getline will give you '\n' at the end. One solution is remove '\n' after getting it. Another solution is do not write the additional 'endl'. for example, for your problem, you can use this code

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



回答5:


cin.ignore() worked for me.

void House::provideRoomName()
{
    int noOfRooms;

    cout<<"Enter the number of Rooms::";
    cin>>noOfRooms;
    cout<<endl;

    cout<<"Enter name of the Rooms::"<<endl;
    cin.ignore();
    for(int i=1; i<=noOfRooms; i++)
    {
        std::string l_roomName;
        cout<<"Room"<<"["<<i<<"] Name::";
        std::getline(std::cin, l_roomName);
    }
}



回答6:


I am writing this answer with the hopes that it may help someone else out there that wants a very simple solution to this problem.

In my case the problem was due to some files having different line endings such as '\r' vs. '\n'. Everything worked fine in windows but then it failed in Linux.

The answer was actually simple. I created a function removeNewLineChar after each line was read in. That way the char was removed. The removeNewLineChar takes in the line that was read in and copies it over character by character into a new string but it avoids copying either of the newline characters.

Here is a full explanation of how that works.

C++ getline reads in the newline character and how to avoid it



来源:https://stackoverflow.com/questions/18725522/getline-keeps-on-getting-newline-character-how-can-i-avoid-this

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!