Getline 不断获得换行符。我怎样才能避免这种情况?

Posted

技术标签:

【中文标题】Getline 不断获得换行符。我怎样才能避免这种情况?【英文标题】:Getline keeps on getting newline character. How can I avoid this? 【发布时间】:2013-09-14 13:16:10 【问题描述】:

基本上,我首先将一个整数作为输入,然后是测试用例。我的每个测试用例都是一个字符串。如果字符串的起始模式与“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

【问题讨论】:

getline(cin,nl) 更改为 cin.ignore() 以在读取 N 后处理该行的其余部分。cin.ignore() 读取并丢弃仍然未从 cin 读取的行的其余部分。 请搜索函数touppertolower。如果将字符转换为大写或小写,则会将比较次数减少一半。 【参考方案1】:

ignore() 函数可以解决问题。默认情况下,它会丢弃所有输入序列,直到换行符为止。

也可以指定其他分隔符和字符限制。

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

你的情况是这样的。

    cin >> N;
    cin.ignore();

【讨论】:

【参考方案2】:

您的cin &gt;&gt;N 停在第一个非数字字符,即换行符处。这个你有一个getline 可以读过去,很好。

之后的每个附加 getline 都会读取整行,包括末尾的换行符。通过输入第二个getline,您将跳过一半的输入。

【讨论】:

【参考方案3】:

所以,你真正的问题不是getline 吃换行符,而是你的第二个getline(cin, ne) 吃换行符......

那是因为你错误地认为你需要两个 getline 操作来读取一行 - 或类似的东西。混合“linebased”和“itembased”输入确实有令人困惑的方式来处理换行符,所以你确实需要一些东西来“跳过” frin cin &gt;&gt; N; 后面留下的换行符,但是一旦你摆脱了它,你只需要一个 @ 987654325@ 阅读并在行尾包含换行符。

【讨论】:

【参考方案4】:

你只需要接受 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"
  

【讨论】:

【参考方案5】:

我正在写这个答案,希望它可以帮助那些想要一个非常简单的解决这个问题的人。

在我的情况下,问题是由于某些文件具有不同的行尾,例如“\r”与“\n”。在 Windows 中一切正常,但在 Linux 中却失败了。

答案其实很简单。在读入每一行后,我创建了一个函数 removeNewLineChar。这样就删除了字符。 removeNewLineChar 接收读入的行并将其逐个字符地复制到新字符串中,但它避免复制任何一个换行符。

这里是它如何工作的完整解释。

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

【讨论】:

这正是我面临的问题。非常感谢。【参考方案6】:

cin.ignore() 为我工作。

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

【讨论】:

【参考方案7】:
std::string line;
std::cin>>std::ws; // discard new line not processed by cin
std::getline(std::cin,line);

来自备注部分https://en.cppreference.com/w/cpp/string/basic_string/getline

When consuming whitespace-delimited input (e.g. int n; std::cin >> n;) any whitespace that follows, including a newline character, will be left on the input stream. Then when switching to line-oriented input, the first line retrieved with getline will be just that whitespace. In the likely case that this is unwanted behaviour, possible solutions include:

An explicit extraneous initial call to getline
Removing consecutive whitespace with std::cin >> std::ws
Ignoring all leftover characters on the line of input with cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); 

【讨论】:

以上是关于Getline 不断获得换行符。我怎样才能避免这种情况?的主要内容,如果未能解决你的问题,请参考以下文章

我怎样才能从一个街区提前归还一些东西?

getline()和get()的使用区别

我怎样才能获得将在其中绘制子字符串的绑定矩形?

带有换行符的 Vista 凭据提供程序

我怎样才能获得 Viber 联系人(姓名和号码)?

我怎样才能获得贝宝的商家帐户 ID?