0

In the following code I can't use the std::string class.

I'm trying to read a file that has empty lines, and I want to ignore the empty lines when I encounter them.

I've tested out some ideas using a simplified example and a made-up text file containing empty lines.

int main() {
    ifstream fin;
    fin.open("test.txt");
    if(fin.fail()){
        cout << "Input file fail.";
        exit(-1);
    }

    char line[10];

    while(!fin.eof()){
       fin.getline(line, 10);
       if(line[0] == '\n')
           cout << "skip" << "\n"; 
       else
           cout << line << "\n";
    }
}

I've also tried things like strlen(line) == 1, but nothing worked so far.

What is the problem?

πάντα ῥεῖ
  • 83,259
  • 13
  • 96
  • 175
Brian
  • 189
  • 2
  • 13
  • 4
    Please see [Why is iostream::eof inside a loop condition considered wrong?](http://stackoverflow.com/q/5605125/2069064) – Barry Feb 13 '16 at 20:26
  • `std::getline()` discards the delimiter, which explains why neither of your solutions will work. – Martin Broadhurst Feb 13 '16 at 20:30
  • *We're not allowed to use the string class* -- So might as well call your course *C programming* instead of *C++ programming*. – PaulMcKenzie Feb 13 '16 at 20:30
  • Teaching C++ while disallowing `std::string` is cruel and unusual. It would be a good idea to encourage your professor to [stop teaching C](https://www.youtube.com/watch?v=YnWhqhNdYyk). – Zulan Feb 13 '16 at 20:34
  • @Barry Always a good notice when seeing that code, but not relevant for the particular case behavior. – πάντα ῥεῖ Feb 13 '16 at 20:39

3 Answers3

1

std::getline() already takes care of the '\n' character (it will be discarded), line[0] would contain '\0' in the case of an empty input.

Just compare for '\0' instead of '\n':

if(line[0] == '\0')
    cout << "skip" << "\n"; 
else
    cout << line << "\n";

I've also tried things like strlen(line) == 1

If so, shouldn't that have been strlen(line) == 0 for an empty line?

πάντα ῥεῖ
  • 83,259
  • 13
  • 96
  • 175
1

There are two problems with your code. The first is that your loop isn't correct. You have to check the result of the getline() call, not eof(). Please see Why is iostream::eof inside a loop condition considered wrong. That restructured loop becomes:

while (fin.getline(line, 10)) {
    ...
}

Next, when you read a line with getline() (and 10 seems really short for a line), the delimiter will not be part of the body. There will not be a \n in line when you're doing reading. You'll just have an empty string. So the right way to discard empty lines is:

while (fin.getline(line, 10)) {
    if (line[0]) {
        // we have contents!
    }
}

Or really, std::string is just way better:

std::string line;
while (std::getline(fin, line)) {
    if (!line.empty()) {
        ....
    }
}
Community
  • 1
  • 1
Barry
  • 247,587
  • 26
  • 487
  • 819
0

std::getline() discards the delimiter \n. But you might also want to consider that on some systems lines may be delimited by \r\n.

Zulan
  • 20,904
  • 6
  • 41
  • 90