13

How can I detect if a line is empty?

I have:

1
2
3
4

5

I'm reading this with istream r so:

int n;
r >> n

I want to know when I reach the space between 4 and 5. I tried reading as char and using .peek() to detect \n but this detects the \n that goes after number 1 . The translation of the above input is: 1\n2\n3\n4\n\n5\n if I'm correct...

Since I'm going to manipulate the ints I rather read them as ints than using getline and then converting to int...

LihO
  • 37,789
  • 9
  • 89
  • 156
bb2
  • 2,452
  • 7
  • 30
  • 44
  • 4
    ¤ Read each line into a `std::string` by using `std::getline`. Check the string length. Use e.g. a `std::istringstream` to read individual items from the line of input. This will also help you with erroneous input. Cheers & hth., – Cheers and hth. - Alf Feb 10 '12 at 21:52
  • 2
    Oh, I just saw the last paragraph, which paraphrased says "I do not want to use the easiest and most reasonable way". In that case there are virtually zillions of more complex ways. Only one's imagination can put limits on the ways to do something in silly-complex fashion. Cheers, – Cheers and hth. - Alf Feb 10 '12 at 21:54
  • 2
    Okay you don't have to be rude. At least I tried different ways before posting this. I just wanted to know if there was another way.I'm just learning c++ atm. Thanks for the istringstream comment though, I'm going to try that mixed with the getline! You can post it as answer if you want, and I'll accept it. – bb2 Feb 10 '12 at 21:57

2 Answers2

26

It could look like this:

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

output:

1 2 3 4 Empty line.
5 Done.

Hope this helps.

LihO
  • 37,789
  • 9
  • 89
  • 156
  • I do need to know about empty line because input is divided by blocks separated by that blank space. And I need to know what data goes to what block. – bb2 Feb 10 '12 at 22:04
  • 2
    @bb2 : In that case I would definitely use `std::getline` to read each line as a `string`. Then you can create temporary `istringstream` based on that string and read from it. I have edited my answer. – LihO Feb 10 '12 at 22:13
  • I've just noticed that solution was also recommended by Alf P. Steinbach in comment to your question. – LihO Feb 10 '12 at 22:15
  • 2
    **Fail**: You are reporting an extra empty line. Doing this `while (is.good())` is practically always wrong and definitely wrong here. Use `while(getline(is, s))` – Martin York Feb 11 '12 at 07:34
  • @LokiAstari: You are right, it's much better. Thank you, I have edited my answer. – LihO Feb 11 '12 at 10:06
6

If you really don't want using getline, this code works.

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

But be aware that this is not portable. When you using system that has different end lines characters than '\n' then would be problem. Consider reading whole lines and then extract data from it.

gumik
  • 593
  • 1
  • 4
  • 14
  • It's not true that this is non-portable. The newline char(s) of the system is converted to and from '\n'. – rasmus Feb 10 '12 at 22:50