Some questions about ios::eof in reading a file

Well, I'm writing a program to read in numbers from input.txt and write out the primes in output.txt. Here's what I have:

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
#include <fstream>
#include <iostream>
#include <conio.h>
using namespace std;

bool IsPrime(int n)
{
	for(int i=2;i<n;++i)
	{
		if(n%i==0)
			return false;
	}
	return true;
}

void main()
{
	int t;
	ifstream fin;
	ofstream fout;
	fin.open("input.txt");
	fout.open("output.txt");
	if(fin==NULL || fout == NULL)
		cout<<"ERROR"<<endl;
	else
	{
		while(fin.eof()==false)
		{
			fin>>t;
			if(IsPrime(t)==true)
				fout<<t<<endl;
		}
		fin.close();
		fout.close();
	}
	getch();
}


input.txt and output.txt would have a format like below
2
6
101
128
17


As much as I understand, the program will read at least once beyond the last valid thing in input.txt and fail there for fin.eof() to be true (is that correct???) So will it read in some garbage value before sop reading in?

My professor also said that it would be a good practice to read from a file like this:
-Read the first thing in the file
-While the end of file flag is not set
+Process what was read
+Read the next thing from the file
Can someone please explain to me why is it a good practice? And what will happen if I don't read the first time outside the loop and just do it like in my program above
Thank you
http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong

you should use
1
2
3
4
5
while( fin >> t ) {
    if( isPrime(t) ) {
        fout << t << endl;
    }
}
instead

BTW :
1
2
3
4
5
6
7
8
9
bool b = true;

if( b ) { }
// is the same as :
if( b == true ) { }
//===========
if( !b ) { }
// is the same as
if( b == false ) {}

Last edited on
The previous answer is correct and useful.

However I just wanted to point out that your code does not match the instructions from your professor. Quote:
My professor also said that it would be a good practice to read from a file like this:
-Read the first thing in the file
-While the end of file flag is not set
+Process what was read
+Read the next thing from the file

In that scenario, the first item is read from the file before the start of the loop. Inside the loop, the item is processed, and the last thing which is done before the end of the loop is to read the next item.

Although that structure is almost correct, there is still an error. That is, when the last item is read from the file, the eof() flag may or may not be set, depending on whether there is any trailing whitespace or newline.

Thus, your professor's version with the errors corrected might look something like this. Notice it does not test for eof() for the reasons mentioned above.
1
2
3
4
5
6
7
8
9
    fin >> t;                       // Priming read
    
    while (fin)                     // check stream is not failed
    {
        if (IsPrime(t))
            fout << t << endl;
            
        fin >> t;                   // Read the next item
    }

though I also agree with the version posted above by shadow fiend as the code is slightly simpler, since it reads the file in only one place instead of two.
One more comment,
1
2
    if(fin==NULL || fout == NULL)
        cout<<"ERROR"<<endl;

The above code is wrong, don't check for NULL. Instead do this:
1
2
    if (!fin || !fout)
        cout<<"ERROR"<<endl;

See
http://www.cplusplus.com/reference/ios/ios/operator_not/
http://www.cplusplus.com/reference/ios/ios/operator_bool/
Topic archived. No new replies allowed.