File I/O semantic error

Hello

Here's my code:

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
52
53
54
55
56
57
#include <iostream>
#include <fstream>

using namespace std;

int main()
{
    ofstream FileOut("Student.txt", ios::out);

    int Roll;
    char Name[50];
    float AvgMarks;

    char choice = 'y';
    int i = 1;

    cout << "\nENTER STUDENT DETAILS:-\n";

    while(choice == 'y' || choice == 'Y')
    {
        cout << "\nEnter details of student : " << i++ << endl;

        cout << "Enter roll number : ";
        cin >> Roll;

        cout << "Enter name : ";
        cin.get();
        gets(Name);

        cout << "Enter average marks : ";
        cin >> AvgMarks;

        FileOut << Roll << "\t" << Name << "\t" << AvgMarks << endl;

        cout << "\nDo you want to enter more info? (Y/N) : ";
        cin >> choice;
    }

    FileOut.close();

    ifstream FileIn("Student.txt", ios::in);

    FileIn.seekg(0);

    while(!FileIn.eof())
    {
        FileIn >> Roll >> Name >> AvgMarks;

        cout << Roll << "\t" << Name << "\t" << AvgMarks << endl;
    }

    FileIn.close();

    cout << "\nPress ENTER to exit...\n";
    getchar();
    return 0;
}


The expected output was:



ENTER STUDENT DETAILS:-

Enter details of student : 1
Enter roll number : 1
Enter name : John
Enter average marks : 85

Do you want to enter more info? (Y/N) : y

Enter details of student : 2
Enter roll number : 2
Enter name : Joey
Enter average marks : 86

Do you want to enter more info? (Y/N) : n
1       John    85
2       Joey    86

Press ENTER to exit...


But the actual output is:


ENTER STUDENT DETAILS:-

Enter details of student : 1
Enter roll number : 1
Enter name : John
Enter average marks : 85

Do you want to enter more info? (Y/N) : y

Enter details of student : 2
Enter roll number : 2
Enter name : Joey
Enter average marks : 86

Do you want to enter more info? (Y/N) : n
1       John    85
2       Joey    86
2       Joey    86

Press ENTER to exit...


Why is the last line of the file displayed two times?

Thanks
Because of this:
1
2
3
4
5
6
    while(!FileIn.eof()) // here you check whether it is eof
    {
        FileIn >> Roll >> Name >> AvgMarks; // here the eof incident happens. If so the variables remain unchanged [from the last time]

        cout << Roll << "\t" << Name << "\t" << AvgMarks << endl;
    }
@coder777


So how do i produce the correct output?
As simple as this:
1
2
3
4
    while(FileIn >> Roll >> Name >> AvgMarks)
    {
        cout << Roll << "\t" << Name << "\t" << AvgMarks << endl;
    }
Last edited on
@coder777

But why does eof() not work in this case? I mean the while loop tests the end of file condition, if false, executes its body. So why does the case of eof happen?
Last edited on
But why does eof() not work in this case?


Because the sequence of events is wrong.
45
46
47
48
49
50
    while(!FileIn.eof())
    {
        FileIn >> Roll >> Name >> AvgMarks;

        cout << Roll << "\t" << Name << "\t" << AvgMarks << endl;
    }

At line 47, an input operation is performed. We don't know whether it was successful or not.
Then line 49, an output line is produced (using the variables that we don't know were successfully read into or not).

After that, control goes back to the top of the loop, and eof() is tested. But that's too late. The horse has already fled the stable.

The other, related point is that testing for eof() is not really appropriate here in any case. Remember that each line in the file ends with a newline character. So after an operation such as FileIn >> AvgMarks; the newline character is not part of the value AvgMarks so it is left in the file buffer. And importantly it means that after reading the last data item from the file, the eof flag is not set. That doesn't happen until the next input operation.
Last edited on
@The Illusionist mirage
Incidentally, unless you invented that yourself, where did you learn to use this "while(!FileIn.eof())" thing? If it's a book, name it so we know who to blame.
Topic archived. No new replies allowed.