简体   繁体   中英

Dynamically allocated array only displaying the last results

I'm creating a program that takes in a students ID, name, and test scores and calculates the total score they receive based on other inputs of possible scores and relative weights. From there, the user will input cutpoint sets to say exactly where the A,B,C,D,F lines are. For example, if the B cutpoint set is at 20.0 and the A cutpoint is at 90.0, anything in between 90 and 20 would receive a grade of a B.

To implement this, I created a struct called Cutpoints that just has this.

struct Cutpoints {
    double a;
    double b;
    double c;
    double d;
};

To contain everything about the students, I created a structure for them called Student:

struct Student {
    int id; // student ID
    char gradeOption; // either G or P
    double totalScore;
    std::string studentName;
    int* rawScores = NULL; // array that holds raw scores for a student
    std::string* finalGrade; // final grade given in course
};

The problem I'm having is with my final grade output. The user enters the amount of cutpoints they want, then you enter the actual cutpoints. Lets say the user enters two rows of cutpoints. I end up getting this output:

2
85.0 75.0 65.0 55.0
80.0 70.0 60.0 50.0
TOTAL SCORES
123 Alex Thornton 79.1
234 Boo Thornton 100
345 Jane Student 92
456 Joe Student 72.4
567 Too-Many Courses 30.8
CUTPOINT SET 1
123 Alex Thornton 
234 Boo Thornton 
345 Jane Student 
456 Joe Student 
567 Too-Many Courses 
CUTPOINT SET 2
123 Alex Thornton B
234 Boo Thornton A
345 Jane Student A
456 Joe Student P
567 Too-Many Courses F

The total scores has no problem outputting and the final grades for the last cutpoint will output correctly, but all the cutpoints before it will not output final grades. I've tried to debug with cout and try and trace it to the problem, but I can't figure out what is going wrong. Here is the code that works specifically with the final grades:

void outputFinalGrade(int numOfStudents, int cutpointAmount, Cutpoints* cut, Student* students) {
    for(int i = 0; i < cutpointAmount; i++) {
        inputCutpoint(i, cut); // get user input for the current set of cutpoints
        getFinalGrade(cutpointAmount, cut, students, numOfStudents);
        /* OUTPUT */
        std::cout << "CUTPOINT SET " << (i + 1) << std::endl;
        for(int j = 0; j < numOfStudents; j++) { // print all students
            std::cout << students[j].id << students[j].studentName << " " << students[j].finalGrade[i] << std::endl;
        } // end inner for (display students)
    } // end outer for
} // end outputFinalGrade

// input cutpoints
void inputCutpoint(int cutpointNumber, Cutpoints* cut) {
        // user inputs cutpoints
        std::cin >> cut[cutpointNumber].a >> cut[cutpointNumber].b >> cut[cutpointNumber].c >> cut[cutpointNumber].d;
}

And here is my (eyesore) method that should store the final grade into the correct array position depending on what position is in the cutpoint:

void getFinalGrade(int cutAmount, Cutpoints* cut, Student* students, int amountOfStudents) {
    for(int j = 0; j < cutAmount; j++) {
        for(int i = 0; i < amountOfStudents; i++) {
            students[i].finalGrade = new std::string[cutAmount];
            // if students grade option is P/NP
            if(students[i].gradeOption == 'P') {
                if(students[i].totalScore >= cut[j].c) { // we pass
                    students[i].finalGrade[j] = "P";
                } else { // we didn't pass
                    students[i].finalGrade[j] = "NP";
                } // end P/NP grade option
            // check grade based on cutpoints for the G option
            } else {
                if(students[i].totalScore >= cut[j].a) {
                    students[i].finalGrade[j] = "A";
                } else if(students[i].totalScore >= cut[j].b) {
                    students[i].finalGrade[j] = "B";
                } else if(students[i].totalScore >= cut[j].c) {
                    students[i].finalGrade[j] = "C";
                } else if(students[i].totalScore >= cut[j].d) {
                    students[i].finalGrade[j] = "D";
                } else {
                    students[i].finalGrade[j] = "F";
                }
            } // end checking statement
        } // end inner for
    } // end outer for
}

Seems to be two main problems with this code:

  1. You are iterating over each cutpoint set inside outputFinalGrade, and inside the loop, you call getFinalGrade, which also iterates over each cutpoint set (even though the cutpoint sets aren't all initialized yet). You might want to change the getFinalGrade to take the cutpoint, and remove the extra outer for loop.

  2. You are re-initializing the final grade each iteration :) this means that every time you iterate, you wipe out the results of the last iteration. This is most likely the cause of your problem:

     students[i].finalGrade = new std::string[cutAmount]; 

There are a number of ways to fix this, move the intialization elsewhere, or simply check for NULL before calling new.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM