如何在C++中从istream对象读取时检测空行?

16

我该如何检测一行是否为空?

我有以下代码:

1
2
3
4

5

我正在使用 istream r 进行阅读:

int n;
r >> n
我想知道何时到达4和5之间的空格。 我尝试以字符方式读取并使用.peek()来检测\n,但这会检测到1后面的\n。如果我没错,上述输入的翻译是: 1\n2\n3\n4\n\n5\n...
由于我将操纵整数,所以我宁愿将它们作为整数读取,而不是使用getline然后转换为整数...

4
使用std::getline将每行读入一个std::string,检查字符串长度。使用例如std::istringstream从输入的每一行中读取单个项目。这也有助于处理错误输入。祝好运! - Cheers and hth. - Alf
2
哦,我刚看到最后一段话,大意是“我不想使用最简单和最合理的方法”。在这种情况下,还有无数更复杂的方法。只有想象力才能限制以愚蠢而复杂的方式完成某事的方法。干杯! - Cheers and hth. - Alf
2
好的,你不必这么无礼。在发帖之前,我尝试了不同的方法。我只是想知道是否还有其他方法。我现在正在学习C++。感谢你的istringstream评论,我将尝试与getline混合使用!如果你愿意,你可以把它作为答案发布,我会接受它。 - bb2
2个回答

31

它可能看起来像这样:

#include <iostream>
#include <sstream>
using namespace std;

int main()
{
    istringstream is("1\n2\n3\n4\n\n5\n");
    string s;
    while (getline(is, s))
    {
        if (s.empty())
        {
            cout << "Empty line." << endl;
        }
        else
        {
            istringstream tmp(s);
            int n;
            tmp >> n;
            cout << n << ' ';
        }
    }
    cout << "Done." << endl;
    return 0;
}

输出:

1 2 3 4 Empty line.
5 Done.

希望这可以帮到你。


我需要了解空行,因为输入是由以该空白行分隔的块组成的。我需要知道哪些数据属于哪个块。 - bb2
2
@bb2:在这种情况下,我肯定会使用std::getline将每一行读取为一个string。然后,您可以基于该字符串创建临时的istringstream并从中读取。我已经编辑了我的答案。 - LihO
我刚刚注意到,Alf P. Steinbach在评论中也推荐了这个解决方案。 - LihO
2
失败:您报告了一个多余的空行。在这里这样做 while (is.good()) 几乎总是错误的,而且肯定是错误的。请使用 while(getline(is, s)) - Martin York
@LokiAstari:你说得对,这样好多了。谢谢,我已经编辑了我的回答。 - LihO

7
如果您真的不想使用getline,这段代码可以工作。
#include <iostream>
using namespace std;


int main()
{
    int x;
    while (!cin.eof())
    {
        cin >> x;
        cout << "Number: " << x << endl;

        char c1 = cin.get();
        char c2 = cin.peek();

        if (c2 == '\n')
        {
            cout << "There is a line" << endl;
        }
    }
}

但要注意,这种方法并不可移植。当你使用的系统具有不同于 '\n' 的行尾字符时,会出现问题。考虑读取整行,然后从中提取数据。


2
这不是不可移植的。系统中的换行字符被转换为 '\n'。 - rasmus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接