-
reading a file
Hi All,
I am having some difficulty reading an additional file - my code is reading the last data twice. I am still pretty new at C++ so I know I am making a simple mistake, but I cannot figure out what it is. I am still in a beginners C++ class and this is part of one of my assignments. Here is the data from the file I am reading (data1.txt):
Smith,Tom
90 100
10 10 10 10 10 10 2 1 10 10 10 10
Jones,Mary
90 90
1 2 3 4 5 6 7 8 9 10 10 10
Hubred,Nicolle
100 100
10 10 10 10 10 10 10 10 10 10 10 10
Ball,Lucille
50 90
10 10 2 7 10 1 1 10 10 10 10 10
I am using structs and an array to store the information (name, midterm grade, final grade, 12 quiz/hw grades). Everything seems to be working fine except Ball,Lucille is printing to the screen twice, rather than once. I am using in_file.eof() to detect the end of the file, but that is not seeming to do the trick. Below is my code - any help you can give would be greatly appreciated!!
Code:
#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;
//structure for a students name, hq/quiz average, midterm and final
//exam grades
struct A_STUDENT
{
string name;
int midterm;
int final;
int hw_quiz;
};
int main()
{
ifstream in_file;
A_STUDENT person;
A_STUDENT hw_quiz_grades[12];
int size = 12;
in_file.open("data1.txt");
if (in_file.fail())
{
cout << "Opening input file \"data1.txt\" failed\n" << endl;
exit(1);
}
while (!in_file.eof())
{
for (int i = 0; i < size; i++)
{
hw_quiz_grades[i].hw_quiz = 0;
}
in_file >> person.name >> person.midterm >> person.final;
for (int i = 0; i < size; i++)
{
in_file >> hw_quiz_grades[i].hw_quiz;
}
cout << person.name << " " << person.midterm << " " << person.final << " ";
for (int i = 0; i < size; i++)
{
cout << hw_quiz_grades[i].hw_quiz << " ";
}
cout << endl;
}
in_file.close();
return 0;
}
-
eof doesn't happen until you try to read a record that isn't there. Since you're already in the middle of the loop when that happens, you can't use eof to control your loop. You'll need to rejigger your loop so that a read happens at the very top as your loop control thing.
-
In this case, you might be able to break out of the loop once the first read op fails:
Code:
if ( !(in_file >> person.name >> person.midterm >> person.final) ) break;
What I would do to make things cleaner is overload the stream insertion and extraction operators (<</>>) for the A_STUDENT struct and then use the read operation's return result in the while loop's conditional. The whole input/output loop then becomes much simpler looking:
Code:
std::istream& operator>>(std::istream& is, A_STUDENT& rhs)
{
// Your code here to read an A_STUDENT struct from file
}
std::ostream& operator<<(std::ostream& os, const A_STUDENT& rhs)
{
// Your code here to write A_STUDENT struct details
}
...
// The new i/o processing loop then reduces all the way down to this.
A_STUDENT person;
while( in >> person )
cout << person;
[edit]Your struct should have an array of quiz grades, not just a single one.[/edit]
-
Thanks hk_mp5kpdw - I used a break statement and that worked great. I also changed my struct to have an array of hw_quiz.
The condensed data above looks great but I am in a beginners class and we have not learned that yet so unfortunately I have to stick with the long way!!
Thanks again for your help.