Hello,

To start thanks in advance for any help. Now I will note this question is about homework so I just want help to get started not everything laid out for me. Ok here is the deal. I have a class called StudentArrayV4, it is a dynamic array of pointers. I also have the class Student that actually holds the student information and is pointed to by StudentArrayV4. I added the ability to save the student data as well as load it from a file. I made sure the code worked by using (!infile.eof) as my test to find the end of file. However, i know .eof can be unreliable so I don't want to use it, not to mention I'd probably lose points on my homework too. The way I was required to set it up was by having the ifstream opened in main and then passed by reference to StudentArrayV4 which then eventually passes it to the Student Constructor. Any ideas on how I can know when I hit the end of the file without using .eof Here is the code for my various methods.

void  StudentArrayV4::read (ifstream& infile){
   StudentArrayV4 loadedFile;
   if (!infile){
      cout << "Error no file found!\n";
   }
   else{
      while (!infile.eof )
      add(infile);
   }
}

void StudentArrayV4::add (ifstream & infile){
   Student **temp = new Student*[numberOfStudents + physicalArraySize];
      for (int j = 0; j < numberOfStudents; j++){
         temp[j] = members[j];
      }   
         delete [] members;
   physicalArraySize += 3;
   members = temp;
   members[numberOfStudents] = new Student(infile);
   numberOfStudents++;
}

Student::Student (ifstream& infile){
   char tempName[300];
   int length;
      infile >> tempName >> idNumber; // loading data from file
            for (int j = 0; j < 3; j++){
                infile >> scores[j];
            }
            length = strlen(tempName);
            name = new char[length + 1]; // for the null character
            strcpy (name, tempName);
            calculateAverageAndGrade();
}

Firstly, using the >> method to read the student name assumes every student has a "one word" name, which is a bit unrealistic. If that is the condition of your problem, then consider

if( infile >> tempName )
    {
         infile >> idNumber; // loading data from file
            for (int j = 0; j < 3; j++){
                infile >> scores[j];
            }
            length = strlen(tempName);
            name = new char[length + 1]; // for the null character
            strcpy (name, tempName);
            calculateAverageAndGrade();
     }

When there is no name left in the file, there's no point in attempting to read further data.

But, you'll have to in some manner return an indicator of whether it was a successful read or not. I don't think using the Student constructor for the reading is a good idea.

Perhaps having the void StudentArrayV4::add () method do the actual reading, to temp variables. If successful, store the read values to the next available Student object.

This line

Student **temp = new Student*[numberOfStudents + physicalArraySize];

confuses me. If you know the number of students, why are you worried about finding end of file? Just loop that number of times when reading. What is physicalArraySize, where does that come from and why are you using it to set number of students in the temp array?

Thanks for the help. The names are one word, the professor wanted it way to make it more simplistic. I couldn't have studentArrayV4 read the file as it is a dynamic array of pointers that points to the students as they are created by the Student Constructor. numberOfstudents is a counter, starts at zero and is incremented for every student made. physical size, which is currently set at 3, helps test the size of the array that way if a student is called to be construted and there is not enough room a new larger array can be created filled with the current student info and then the new student can be added. i.e. the array starts blank and has three elements. If a fourth student is called for then a new array is created that has six elements, the data from the 3 element array is copied over and the 3 element array is deleted. Finally the student** (pointer to array of pointers) is redirected to the new array. The process can be repeated as many times as needed.

I'm not sure whether this is what you are looking for, but try this:

infile.seekg(0, std::ios::end);
long fileEnd = infile.tellg();
long counter = 0;
while(counter != fileEnd) {
      // do something
      ++counter;
} // end while

What's happening here is that you make the "get" pointer to point to the end of your file, and store this position(which will be the size of your file in bytes) in a variable (through tellg() ). Then you can iterate through the file with a simple loop, whilst updating the current position, and check that it hasn't exceeded the end-of-file.

Apart from this, I would suggest you using the concept of "binary" files to store class or structure data. This way, you wouldn't have to mess around with so many arrays and loops.

Hope this helped!

// EDIT: Looks like vManes solved this as I was typing... :)

Edited 7 Years Ago by amrith92: Looks like I was too late in aswering :)

This article has been dead for over six months. Start a new discussion instead.