Hello, this is my first time posting here so im sorry for doing anything wrong. Also I am kinda new at programming so bare with me.

I am currently working on a function that basically reads a list of double values and assigns them to an array. But I ran across this problem that I have no idea what to do about. I've searched everywhere but seems like no one really had this problem, so I must be doing something completely wrong.

Here is the code I am working with:

void Employee::readSalary(Employee emp[])
{
	int i = 0;
	double thisSalary;
	ifstream empFile;

	empFile.open("salary.txt");
	while(!empFile.eof())
	{
		empFile >> thisSalary;             //reads in the double value
		emp[i].setSalary(thisSalary);    //assigns to the array
		cout << emp[i].getSalary() << endl;   //for test purposes
		i++;
	}
	empFile.close();
}

Now in salary.txt I have 3 double values such as:

5.5
7.5
9.5

When this code runs, it outputs:
5.5
7.5
9.5
9.5

I have no idea why it reads in the last value twice and assigns it to two different array elements. Maybe I am not reading the double value the correct way? or is there something I am missing about the eof() function. I get the same problem if I read an Int, but I have no problem with strings. Any kind of help is GREATLY appreciated, I've been stuck on this for a while now. Thanks in advance.

-Qas

Recommended Answers

All 10 Replies

The problem is the way you formed that while loop -- it reads the last entry in the file twice. Here is the correct way to code it. Notice that eof() is not necessary.

while(empFile >> thisSalary)
	{
		emp[i].setSalary(thisSalary);    //assigns to the array
		cout << emp[i].getSalary() << endl;   //for test purposes
		i++;
	}

Hello, this is my first time posting here so im sorry for doing anything wrong. Also I am kinda new at programming so bare with me.

I am currently working on a function that basically reads a list of double values and assigns them to an array. But I ran across this problem that I have no idea what to do about. I've searched everywhere but seems like no one really had this problem, so I must be doing something completely wrong.

Here is the code I am working with:

void Employee::readSalary(Employee emp[])
{
	int i = 0;
	double thisSalary;
	ifstream empFile;

	empFile.open("salary.txt");
	while(!empFile.eof())
	{
		empFile >> thisSalary;             //reads in the double value
		emp[i].setSalary(thisSalary);    //assigns to the array
		cout << emp[i].getSalary() << endl;   //for test purposes
		i++;
	}
	empFile.close();
}

Now in salary.txt I have 3 double values such as:

5.5
7.5
9.5

When this code runs, it outputs:
5.5
7.5
9.5
9.5

I have no idea why it reads in the last value twice and assigns it to two different array elements. Maybe I am not reading the double value the correct way? or is there something I am missing about the eof() function. I get the same problem if I read an Int, but I have no problem with strings. Any kind of help is GREATLY appreciated, I've been stuck on this for a while now. Thanks in advance.

-Qas

The problem is the way you have designed the loop. It is a very common problem and underscores the perils of using the eof () function. The eof () function does not return false when it has reached the end of the file. It returns false when it attempts to read in a value and does not succeed. When that failure occurs, since it could not read in a new value, it keeps whatever value it had in that variable before. It has three successful reads from the file, then a fourth unsuccessful read. By the time it has the unsuccessful read, it is already inside the while loop. Thus you go through the while loop four times, not three.

You have a few options for a solution. One, call the eof () function inside the loop and if it fails, bypass the rest of the code in the loop, like this:

while(!empFile.eof())
	{
		empFile >> thisSalary;             //reads in the double value
                if (!empFile.eof ())
                {
		     emp[i].setSalary(thisSalary);    //assigns to the array
		     cout << emp[i].getSalary() << endl;   //for test purposes
		     i++;
                }
	}

Two, change your loop so that you don't use the eof () function:

while(empFile >> thisSalary)
	{
	             emp[i].setSalary(thisSalary);    //assigns to the array
		     cout << emp[i].getSalary() << endl;   //for test purposes
		     i++;
	}

The loop above does not have the same problem as your original loop. It will fail during the while loop condition and thus will only go through the while loop three times, not four.

Just hit preview and Ancient Dragon beat me to it with the same advice. :(

Just hit preview and Ancient Dragon beat me to it with the same advice. :(

Yes, because I think most experienced programmers will agree that is the best way to code it. There are other ways, but IMO they are just more clumbsy and less efficient.

Yes, because I think most experienced programmers will agree that is the best way to code it. There are other ways, but IMO they are just more clumbsy and less efficient.

Yes, probably true. I just broke a couple of years' habit of using eof () when I noticed everyone on this forum seems to recommend against it. It makes sense, since eof () often seems to require workarounds. Maybe I should stop offering suggestions on how to work around the potential eof () pitfalls and just offer the solution that doesn't use it. Might save me some typing. :). Do you ever find a good occasion to use eof () or should we simply try to banish it from our brains?

>> Do you ever find a good occasion to use eof ()
I haven't ever had an occations to use it. But that doesn't mean there is no use for it at all.

>> Do you ever find a good occasion to use eof ()

Do you ever use it as part of a validation sequence? Specifically, if you read the file with this:

while(fin >> sample)

how do you know why the loop terminates? That is did the loop terminate because the file was read completely so EOF was found and fin went into fail state secondary to that, or was the file corrupted somehow and fin went into fail state secondary to that. The answer is to call eof(). If it returns true, then the file was read completely. If not, the file was corrupted somehow. Or is there some other way to accomplish this task?

If the loop terminates does it really matter whether eof was reached or the file was corrupt? Yes, it might in more complex programs because if the program detected corruption then it could just abort the entire transactions and not do anything except issue an error message.

So to use eof() at all would depend on the complexity of the program. After the loop ends you could test for eof() just to insure eof actually occurred. But that would be outside the loop, not part of the loop.

Is there another way you can confirm the entire file was read if you don't know ahead of time what's in the file?

Thank you guys so much. I didn't know that eof() worked liked that because our teacher told us otherwise. Im most likely going to avoid using eof() from now on. Thanks again.

Is there another way you can confirm the entire file was read if you don't know ahead of time what's in the file?

After the loop finishes, call tellg() to get the current pointer location (-1 is failure), then seek to the end of the file and call tellg() again. Compare the two values.

Or just simply check eof() after the loop finishes.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.