Simple program opens a text file and counts all the lines. Then it returns the pointer to the beginning of the file and starts pulling in the lines for data manipulation.

The Problem: If the file "triangle.txt" ends with a newline everything works fine until the last while loop which becomes an infinite loop. When the newline is removed the output is fine. Why does a newline at the end of a text file break getline the second time through a file?

#include <iostream>
#include <fstream>
#include <string> //strings strtok strtol
using namespace std;

int main()
{
ifstream ftext;

ftext.open("triangle.txt",fstream::in);

if (!ftext.is_open()){
    cout<< "Error opening file.";
    return 0;
}

int size = 0;
string row;
while (!ftext.eof()){
  getline(ftext,row);
  size++; //size will equal the number of rows
}
cout<< "This pyramid is " << size<< " stories tall.\n";

//problem starts here...
ftext.seekg(0, ifstream::beg); //move back to beginning
ftext.clear(); //reset flags

while (!ftext.eof()){
    getline(ftext,row);//with \n at eof this pulls in nothing
    cout<<row.data()<<"\n"
}

}

Simple program opens a text file and counts all the lines. Then it returns the pointer to the beginning of the file and starts pulling in the lines for data manipulation.

The Problem: If the file "triangle.txt" ends with a newline everything works fine until the last while loop which becomes an infinite loop. When the newline is removed the output is fine. Why does a newline at the end of a text file break getline the second time through a file?

#include <iostream>
#include <fstream>
#include <string> //strings strtok strtol
using namespace std;

int main()
{
ifstream ftext;

ftext.open("triangle.txt",fstream::in);

if (!ftext.is_open()){
    cout<< "Error opening file.";
    return 0;
}

int size = 0;
string row;
while (!ftext.eof()){
  getline(ftext,row);
  size++; //size will equal the number of rows
}
cout<< "This pyramid is " << size<< " stories tall.\n";

//problem starts here...
ftext.seekg(0, ifstream::beg); //move back to beginning
ftext.clear(); //reset flags

while (!ftext.eof()){
    getline(ftext,row);//with \n at eof this pulls in nothing
    cout<<row.data()<<"\n"
}

}

I don't get an infinite loop. Not sure what your input file is. However, try switching the order of these two lines and see if you get better results.

//problem starts here...
ftext.seekg(0, ifstream::beg); //move back to beginning
ftext.clear(); //reset flags

I don't get an infinite loop. Not sure what your input file is. However, try switching the order of these two lines and see if you get better results.

//problem starts here...
ftext.seekg(0, ifstream::beg); //move back to beginning
ftext.clear(); //reset flags

Okay... that worked. I don't get it. I'll read more into what clear() does.

Avoid Loop Control Using eof

I've never been able to get getline the member function to work properly. getline(istream,string) works fine and doesn't have the mentioned loop control error.

I'll try the file >> i method though since it'll probably reduce operating time. Thanks.

Wish it let me edit my post. Anyways, thanks fer the tip Dave. It cut my program run time down to 1/33rd of the original. Remarkable.

Okay... that worked. I don't get it. I'll read more into what clear() does.

When you hit the end-of-file, your ifstream was put into a failed state. seekg needs an ifstream that's not in a failed state to do its job, so seekg never put the pointer at 0, as requested. clear () puts the ifstream into a "good" state again (clears the error bits), so you should clear those error bits BEFORE using seekg (or any other ifstream command) to make sure it has the ability to do its job.

This question has already been answered. Start a new discussion instead.