0

I'll put the program requirements below. I'm new to this, so I would sincerely appreciate as much explanation as possible to help me learn. As it stands, both my pass.txt file AND my fail.txt file are only displaying information from the LAST known user input (each text file only shows ONE student). I'm guessing my array is getting constantly overwritten? How should I fix this?

This program output will result in two output text files. Write a program that prompts a user to enter the following data for 5 students: student name, student ID, exam-1 grade, exam-2 grade, final exam grade, lab grade and homework grade.

The FINAL SEMESTER GRADE of each student is calculated as follows: • 15% - Exam-1 Grade • 15% - Exam-2 Grade • 20% - Final Exam Grade • 40% - Lab Grade • 10% - Homework Grade

Once the final semester grade is calculated, the program should call the function giveBonus( ) to give each student 3 points in addition to the original score. However, the new final grade cannot exceed 100. If it is higher than 100, the function must change the new score to 100.

Save the name, ID and grades of all students who pass the test in the file "pass.txt". Also save the name, ID and grades of students who fail the test in the file "fail.txt". The passing score is 60.

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

using namespace std;

struct students
    //Students structure created to hold the following data for 5 students: student name, student ID, exam-1 grade, exam-2 grade, final exam grade, lab grade and homework grade.
{
    string name; //student's name 
    int ID{}; //student's ID 
    double exam1{}, exam2{}, final{}, lab{}, homework{}, avg{}; 
};

void getDetails(students& student)
//user input to retrieve student name, student ID, exam-1 grade, exam-2 grade, final exam grade, lab grade and homework grades for the 5 total students
{
    cout << "Enter student name: ";
    cin >> student.name;

    cout << "Enter student ID: ";
    cin >> student.ID;

    cout << "Enter their grade for the first exam: ";
    cin >> student.exam1;

    cout << "Enter their grade for the second exam: ";
    cin >> student.exam2;

    cout << "Enter their grade for the final exam: ";
    cin >> student.final;

    cout << "Enter their lab grade: ";
    cin >> student.lab;

    cout << "Enter their homework grade: ";
    cin >> student.homework;

    cout << "\n";

}

double calculateFinalGrade(students& student)
//calculate the preliminary final semester grade for each individual student
{
    double avg;

    avg = ((student.exam1 * .15) + (student.exam2 * .15) + (student.final * .20) + (student.lab * .40) + (student.homework * .10));

    return avg;
}

double giveBonus(students& student)
//function to give students an additional 3 pts added to their final grade; however, students cannot exceed 100 total points
{
    student.avg += 3;
    if (student.avg > 100)
    {
        student.avg = 100;
    }
    return student.avg;
}

void print(students& student)
//output student data to one of two text files based on their final avg
{
    ofstream outPass; //output pass.txt file stream variable 
    ofstream outFail; //output fail.txt file stream variable 

    if (student.avg >= 60) //if the student's average is GREATER than or equal to 60, then output is directed to "pass.txt" file
    {
        //create and open text file for students whose avg is GREATER than 60
        outPass.open("pass.txt", ios::out); //creating pass text file to house student info
        outPass << fixed << showpoint;
        outPass << setprecision(2); //set precision to 2 decimal places for grades

        outPass << "Student Name" << setw(15) << "Student ID" << setw(13) << "Exam 1" << setw(14) << "Exam 2" << setw(18) << "Final Exam" << setw(16)
            << "Lab Grade" << setw(20) << "Homework Grade" << setw(20) << "Adjusted Average" << endl;

        //passing these values to "pass.txt" file
        outPass << student.name << setw(19) << student.ID << setw(16) << student.exam1 << setw(14) << student.exam2 << setw(16) << student.final << setw(17)
            << student.lab << setw(18) << student.homework << setw(17) << student.avg << endl;
    }
    else //if the student's average is LESS THAN 60, then output is directed to "fail.txt" file
    {
        //create and open text file for students whose avg is less than 60
        outFail.open("fail.txt", ios::out); //creating output fail file to house student info 
        outFail << fixed << showpoint;
        outFail << setprecision(2); //set precision to 2 decimal places for grades

        outFail << "Student Name" << setw(15) << "Student ID" << setw(13) << "Exam 1" << setw(14) << "Exam 2" << setw(18) << "Final Exam" << setw(16)
            << "Lab Grade" << setw(20) << "Homework Grade" << setw(20) << "Adjusted Average" << endl;

        //passing these values to "fail.txt" file
        outFail << student.name << setw(19) << student.ID << setw(16) << student.exam1 << setw(14) << student.exam2 << setw(16) << student.final << setw(17)
            << student.lab << setw(18) << student.homework << setw(17) << student.avg << endl;
    }
    outPass.close(); //closing "pass.txt" file
    outFail.close(); //closing "fail.txt" file
}

int main()
{
    students studentArray[5]; //array to hold the student's data 
    
    for (int i = 0; i < 5; i++) //iterate through the 5 total students
    {
        cout << "Enter details for student " << (i + 1) << endl;

        getDetails(studentArray[i]); //get information relating to each of the 5 students

        studentArray[i].avg = calculateFinalGrade(studentArray[i]); //calculate the final grade 

        studentArray[i].avg = giveBonus(studentArray[i]); //assign additional 3 bonus points, if necessary
    }

    for (int i = 0; i < 5; i++)
    {
        print(studentArray[i]);
    }

    return 0;
}
1
  • When you write code, it is best to implement new functionality in isolation as much as possible. If you want to 1) have a complex data structure, 2) handle an array, and 3) read and write a file, develop those three things separately, and don't attempt to dovetail them until all three are working perfectly. If you try to write all three at once, the code will fail and you won't know where the bugs are. Commented Aug 27, 2021 at 17:01

1 Answer 1

1

Each time you open the pass or fail file, you overwrite it.

Either:

  • stop opening the pass and/or fail files for each student

    (instead you can open both files once, and pass them to your mis-named "print" function)

    or

  • open the pass and fail files with the append flag ios::app

The use of these flags is described in the docs for std::basic_filebuf::open - note the Action if file already exists column explicitly says of opening with just the out flag as you're currently doing:

Destroy contents

which is what it's doing.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.