需要帮助将当前学生的记录存储在学生数组中

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

我必须开发一个 C++ 程序,从文件中读取学生的姓名和分数,并将它们存储在 Student 结构对象数组中,然后根据以下标准计算并显示每个学生的期末成绩:期中考试是占期末成绩的25%,期末考试占期末成绩的25%,4次实验的平均成绩占期末成绩的50%。

但是我的知识“有限”,而且在使用结构方面我的知识更多,所以有些事情我不确定如何做或实现(看看下面程序中的评论,基本上我需要帮忙)。我已经尝试了一些方法,但到目前为止 none 工作正常。不幸的是,我无法更改他们提供给我的大部分“模板”(他们为我提供了变量,或者更确切地说是其中的一些变量,letterGrade、Student students[24]、newStudent 等。) ......所以这让我的事情变得有点复杂......我不是那些通常寻求帮助的人之一。其实我很想自己解决,但是时间不多了。。。 我会很感激一些指点或其他东西,谢谢。

The format of the file is ---
      // student name
      // midterm exam scores, final exam scores
      // lab1 score, lab2 score, lab3 score, lab4 score

例如,

Joe Doe
90.8 89.5
67 89.2 99.0 100.0
Susan F. Smith
95.5 94.0
78.5 90 87.5 57
Sam Grover
78 100.0
79.5 69.4 90.0 88.5

这是我到目前为止所做的:

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


using namespace std;


/* structure */
struct Student {
        string name;
        double midTerm;
        double finalExam;
        double lab1;
        double lab2;
        double lab3;
        double lab4;
};

/* function prototype */
double calculateGrade(Student s);


/* main function */
int
main(void)
{
        Student newStudent;
        Student students[24];
        ifstream inFile;
        int numStudent = 0;
        char letterGrade = ' ';


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

        // read the first student’s record, write some code here

        double pct;

        while (inFile) {
                // call calculateGrade function to calculate student’s final numeric score
                // and update student’s record, write some code here
                pct = calculateGrade(newStudent);

                // store the current student record in the students array and update numStudent
                // write some code here
           
                // ignore the ‘\n’ at the end of current student record in the data file
                // before reading next student record, write your code here

                 // read next student record, write some code here

                numStudent++;
        }

        for (int i = 0; i < numStudent; i++) {
                if (pct >= 90.0)
                        letterGrade = 'A';
                else if (pct <= 89.9 && pct >= 80.0)
                        letterGrade = 'B';
                else if (pct <= 79.9 && pct >= 70.0)
                        letterGrade = 'C';
                else if (pct <= 69.9 && pct >= 60.0)
                        letterGrade = 'D';
                else
                        letterGrade = 'F';

                cout << students[i].name << "'s final grade is " << pct
                     << "% (grade: " << letterGrade << ")" << endl;
        }
        exit(EXIT_SUCCESS);
}


double
calculateGrade(Student s)
{
        double exams, labs;

        exams = 0.25 * (s.midTerm) + 0.25 * (s.finalExam);
        labs = 0.125 * (s.lab1 + s.lab2 + s.lab3 + s.lab4);

        return (exams + labs);
}

输出示例为:

David Smith’s final grade is 85.42% (grade: B)
Ian Davis's final grade is 97.34% (grade: A)

...

你应该使用 C++ 的好东西,并学会更保守地使用惯用语。

main 应为 int main()int main(int argc, char *argv[])。在某些环境中,您也可以使用 int main(int argc, char *argv[], char **environ),但永远不要使用丑陋的 void main()。尽管在 C++ 中是等效的 int main(void) 只会让未来的读者感到不安。

在 C++ 中,class(或结构,因为它们是同一事物)可以包含方法。与其使用作为 class 实例的单个参数构建自由函数,不如从中创建一个方法通常更好。

当您检测到错误情况并写入致命错误消息时,您不应继续程序流程。

注入器(resp.extractor)可用于直接从(rest.into)流中提取(resp.write)一个对象。它通常会给出更惯用的代码。

正如您所说 Student students[24] 提供的,我保留了它,但实际上单个学生可能是因为您可以在阅读时打印。这里我把记录的阅读和打印分开了。

所以这是一个可能的代码:

#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';
}