1
ifstream file("file.txt");
 if(file.fail())
{
cout<<"Could not open the file";
exit(1);
}
else
{
      while(file)
      {
        file.getline(line[l],80); 
                          cout<<line[l++]<<"\n";
      } 
}

I am using a two dimensional character array to keep the text (more than one line) read from a file to count the number of lines and words in the file but the problem is that getline always reads an extra line.

user971089
  • 53
  • 1
  • 3
  • 5
    What's up with your code formatting? –  Sep 29 '11 at 12:41
  • You never check whether `getline` succeeds before printing the line that it is supposed to have read. If you check whether `getline` succeeded you will almost certainly find that it is not reading an extra line. This is (essentially) a duplicate of the many `while (!feof(...` questions. – CB Bailey Sep 29 '11 at 12:51
  • E.g. http://stackoverflow.com/questions/2251433/checking-for-eof-in-stringgetline http://stackoverflow.com/questions/5837639/eof-bad-practice – CB Bailey Sep 29 '11 at 12:54
  • On thing to also remember is that getline can possibly read other end of line characters that are not the default delimiter such as reading in '\r' when it's expecting '\n'... here is a more description post to that problem https://beginningprogrammer.com/programming/c-getline-reads-in-the-new-line-character/ – FernandoZ Feb 16 '19 at 05:19

5 Answers5

4

Your code as I'm writing this:

ifstream file("file.txt");
 if(file.fail())
{
cout<<"Could not open the file";
exit(1);
}
else
{
      while(file)
      {
        file.getline(line[l],80); 
        cout<<line[l++]<<"\n";
      } 
}

The first time getline fails, you still increment the line counter and output the (non-existing) line.

Always check for an error.

extra advice: use std::string from the <string> header, and use its getline function.

cheers & hth.

swimfar
  • 147
  • 6
Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
2

The problem is when you're at the end of the file the test on file will still succeed because you have not yet read past the end of file. So you need to test the return from getline() as well.

Since you need to test the return from getline() to see if it succeeded, you may as well put it right in the while loop:

while (file.getline(line[l], 80))
    cout << line[l++] << "\n";

This way you don't need a separate test on file and getline().

Ferruccio
  • 98,941
  • 38
  • 226
  • 299
1

This will solve your problem:

ifstream file("file.txt");
if(!file.good())
{
  cout<<"Could not open the file";
  exit(1);
}
else
{
  while(file)
  {
    file.getline(line[l],80);
       if(!file.eof())
          cout<<line[l++]<<"\n";
  } 
}

Its more robust

Shravan
  • 2,809
  • 2
  • 18
  • 39
1

Does the file end with a newline? If it does, the EOF flag will not be triggered until one extra loop passes. For example, if the file is

abc\n
def\n

Then the loop will be run 3 times, the first time it will get abc, the second time it will get def and the third time it will get nothing. That's probably why you see an additional line.

Try checking the failbit on the stream AFTER the getline.

Foo Bah
  • 25,660
  • 5
  • 55
  • 79
1

Only do the cout if file.good() is true. The extra line you're seeing comes from the last call to file.getline() which reads past the end of the file.

Kusalananda
  • 14,885
  • 3
  • 41
  • 52