Need help to store the record of the current student in the students array

Solution 1:

You should use the C++ goodies, and learn to be more conservative with the idioms.

main should be int main() or int main(int argc, char *argv[]). On some environments you can also use int main(int argc, char *argv[], char **environ) but never use the ugly void main(). Despite being equivalent in C++ int main(void) will only unsettle future readers.

In C++ a class (or a struct because it is the same thing) can contain methods. Instead of building a free function using a single argument that is an instance of a class it is generally better to make a method from it.

When you detect an error condition and write a fatal error message, you should not continue the program flow.

The injectors (resp. extractors) can be used to directly extract (resp. write) an object from (rest. into) a stream. It generally gives a more idiomatic code.

As you said that Student students[24] was provided I kept it, but in fact a single Student could be because you could print at read time. Here I have separated the reading of the records from the prints.

SO here is a possible code:

#include <iostream>
#include <string>
#include <fstream>

// avoid using namespace std because it really import too many symbols
using std::string;
using std::ifstream;
using std::istream;
using std::cerr;
using std::cout;
using std::endl;

/* structure */
struct Student {
    string name;
    double midTerm;
    double finalExam;
    double lab[4];     // making lab an array allows iterating on it

    // you can directly "cache" the computed values in the object itself
    double grade;
    string letterGrade;

    /* function prototype - better to make it a method */
    void calculateGrade();
};

// an extractor for the Student class
istream& operator >> (istream& in, Student& student) {
    if (!std::getline(in, student.name)) return in;  // immediately give up on eof
    in >> student.midTerm >> student.finalExam;
    for (double& lab : student.lab) {
        in >> lab;
    }
    if (in) {
        student.calculateGrade();
        // skip the end of last line because we want to use getline...
        if (in.ignore().eof()) {     // but do not choke on end of file
            in.clear();
        }
    }
    return in;
}

/* main function */
int
main()
{
    Student newStudent;
    Student students[24];
    ifstream inFile;
    unsigned nStudents = 0;


    inFile.open("students.txt");
    if (!inFile) {
        cerr << "Unable to open file.\n";
        return EXIT_FAILURE;
    }

    // C++ allows to directly iterate any container including a plain array
    for (Student& student : students) {
        inFile >> student; // as we iterate through references we can change the object
        if (inFile) {
            nStudents++;
        }
        else {    // give up on error or eof
            if (!inFile.eof()) {   // but only write a message on error
                cerr << "Error reading file.\n";
            }
            break;
        }
    }

    // time to display the results
    for (int i = 0; i < nStudents; i++) {
        cout << students[i].name << "'s final grade is " << students[i].grade
            << "% (grade: " << students[i].letterGrade << ")" << endl;
    }

    exit(EXIT_SUCCESS);
}

// the method implementation
void
Student::calculateGrade()
{
    double exams, labs;

    exams = 0.25 * (midTerm) + 0.25 * (finalExam);
    labs = 0.125 * (lab[0] + lab[1] + lab[2] + lab[3]);

    grade = (exams + labs);
    if (grade >= 90.0)
        letterGrade = 'A';
    else if (grade <= 89.9 && grade >= 80.0)
        letterGrade = 'B';
    else if (grade <= 79.9 && grade >= 70.0)
        letterGrade = 'C';
    else if (grade <= 69.9 && grade >= 60.0)
        letterGrade = 'D';
    else
        letterGrade = 'F';
}