Iterating a file

I have a school assignment where I have to work with memory allocation.

I have to iterate a file and get the content of the file into an object.

Something like that:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <iostream>
#include <fstream>
#include <sstream>

using namespace std;

class Worker
{
public:

    Worker () = default;

    void setInfo(string info)
    {
        stringstream inf(info);

        inf >> name >> salary;

    }
    string name;
    int salary;
};

void loadData()
{
    ifstream file("workers.txt", ios::in);

    string info;

    if(file)
    {
        int num = 0;

        while ( getline(file, info) )
        {
            ++num;
        }

        Worker workers = new Worker[num];

        int i = 0;

        while (getline(file, info))
        {
            workers[ i++ ].setInfo(info);
        }

        file.close();
    }
}


The problem is, it is not loading any worker info into the object.
When debugging I saw that the program is not entering the second loop at all, thus the reason why.

My guess is that the getline() function in the first loop already reached the end of the file so it checks for negative in the second loop.
If so, is there a way to like reset the position of the getline() to the beginning of the file?? Or should I create another ifstream for the second loop.

I also tried for file iteration this:
1
2
3
while( ! file.eof() )
{
}


But it just doesn't break out of the loop and runs infinitely.

Any help would be appreciated!
thanks!
Last edited on
If you can design the file yourself, you could put a number at the top indicating the number of entries.

But barring that, use:
1
2
file.clear();
file.seekg (0, ios::beg);


before the second getline loop.
Don't use eof. Won't help.
Last edited on
@Ganado thanks for the quick answer and solution.

However, I am having trouble understanding what does the clear() does exactly. I have googled it and went on to the documentation here in the site but I haven't fully understood it yet.
Why seekg() needsclear() to work properly?

Also why eof won't help?
Actually, apparently as of C++11, you don't need the file.clear() first.

But the point of clear() is that it resets the failure flag of the file stream.
If the failure flag of the stream is set, it won't get any more input. One of the ways that it's set is when you reach the end of the file.

Looping on the actual extraction of data is always the best thing to do. That way, as soon as you didn't get input, the loop will end. You'll never even have the chance of accidentally using bad data.

Looping on eof can introduce subtle differences in behavior.
For example, compare these two programs:
mainA
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main()
{
	ifstream file("foo.txt");
	while (!file.eof())
	{
		string line;
		getline(file, line);
		cout << line << '\n';
	}
	cout << "<end of program>\n";
}

mainB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main()
{
	ifstream file("foo.txt");
	string line;
	while (getline(file, line))
	{
		cout << line << '\n';
	}
	cout << "<end of program>\n";
}


foo.txt
cat
dog
mouse


If foo.txt ends with no newline, then both programs will behave the same.
But if foo.txt ends with a newline, then the final getline will fail to extract data, and an empty line will be printed out in mainA, while there will be no difference in mainB. This is because the EOF was not tripped by the previous call to getline, so the loop still enters. But now there's no more input from getline, so the getline call will fail, but there's nothing to check the return value of getline before it's printed.

This is more important if you're looping over something with a fixed size, like an array. Going even just one past the end of the array is a buffer overflow.
Last edited on
Actually, apparently as of C++11, you don't need the file.clear() first.

Without file.clear() it doesn't work correctly.

The two examples helped a lot as I now I understand it well, thanks.
Topic archived. No new replies allowed.