I'm doing the following program:
Programming teachers want to create a program that calculates students' end-of-semester grade. Currently, all students' partial grades are in a text file with the following format:
<first_name> <last_name1> <last_name2> | <AC1> <AC2> <AC3> <AC4> <AC5> <AC6> <AC7> <AC8> <AC9> <AC10> | <project 1> <project 2> <project 3> <report> | <exam>
For example:
Joan Gomez Garcia | 8.0 9.0 7.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 | 10.0 9.0 8.5 9.0 | 6.0
Juan Perez Gonzalez | 3.0 3.0 4.8 5.0 5.0 4.0 6.0 2.0 0.0 0.0 | 8.0 7.5 7.0 8.0 | 7.5
Marta Bonet Call | 6.0 7.0 7.0 8.0 8.0 9.0 10.0 10.0 0.0 | 9.0 9.0 9.0 10.0 | 5.5
Jordi Fernandez Bou | 10.0 10.0 10.0 10.0 10.0 10.0 10.0 10.0 10.0 | 10.0 10.0 10.0 10.0 | 3.5
All values are separated by a space and there is a slash ('|') between the continuous assessment marks, the project marks and the final exam mark. This information must be stored in a structure of type Student. You will find its definition in the typedef of the grades.h file shown below.
Continuous evaluation 1 should be stored in box CA[0], continuous evaluation 2 should be stored in CA[1], and so on until continuous evaluation 10. The grade for practice 1 should be saved in project[0], practice 2 should be saved in project[1] and practice 3 should be saved in project[2]. The memory note must be saved in the report field. Finally, the exam grade must be saved in final_exam.
To calculate each student's final grade, the following calculation must be done:
Semester Grade = 50% Knowledge Grade + 50% Project Grade
The Knowledge grade is the highest value between:
Knowledge Grade = 70% Final Exam + 30% Average of the 10 CAs
or
Knowledge Grade = 100% Final Exam
The practice grade is calculated as:
Project Grade = 30% Project 1 + 30% Project 2 + 30% Project 3 + 10% Report
The record of each student with the final grade calculated must be saved in a binary file called "students.bin". Applying the module concept, we want to create a module to solve it made up of the files grades.h and grades.c. The grades.h file is as follows:
#ifndef _GRADES_H
#define _GRADES_H
#include <stdio.h>
#define MAX 100
#define MAX_STR 50
typedef char String[31];
typedef struct {
String first_name;
String last_name1;
String last_name2;
float CA[10];
float Project[3];
float report;
float final_exam;
float sem_grade;
} Student;
int loadGrades(char filename[MAX_STR], Student students[MAX]);
void computeGrades(Student students[MAX], int n_students);
void save(Student students[MAX], int n_students);
void updateFile();
#endif
Your task is to write the contents of the grades.c file. The loadGrades() function opens and reads the contents of filename and stores all the information in the students array and also returns the number of students that have been read from the file. The computeGrades() procedure calculates the final semester grade taking into account CAs, projects and the final exam and updates the sem_grade field. The save() procedure saves the entire contents of the array students in a binary file ("students.bin") of type Student.
Finally, the grading system indicates that students who have obtained a grade of 5.0 or higher on the semester grade but do not obtain at least a grade of 4.0 on the final exam will obtain a 4.0 as the final grade of the semester. It will be necessary to search the entire Students binary file ("students.bin") for these cases and change all semester grades where this situation occurs. This is what the updateFile() function will do.
The main is:
#include <stdio.h>
#include "grade.h"
int main()
{ char filename[MAX_STR];
Student students[MAX];
int n_students = 0;
printf("Enter filename: ");
scanf("%s", filename);
n_students = loadGrades(filename, students);
computeGrades(students, n_students);
save(students, n_students);
updateFile();
return 0;
}
This is the editable code:
int loadGrades(char filename[], Student students[]) {
char buffer[MAX_STR];
int n_students = 0;
int i = 0;
int j = 0;
FILE *fitxer = NULL;
fitxer = fopen(filename, "r");
if (NULL == fitxer) {
printf("error");
} else {
fscanf(fitxer, "%s", students[i].first_name);
while (!feof(fitxer)) {
fscanf(fitxer, "%s", students[i].last_name1);
fscanf(fitxer, "%s", students[i].last_name2);
fscanf(fitxer, "%s", buffer);
for (j = 0; j < 10; j++) {
fscanf(fitxer, "%f", &students[i].CA[j]);
}
fscanf(fitxer, "%s", buffer);
for (j = 0; j < 3; j++) {
fscanf(fitxer, "%f", &students[i].Project[j]);
}
fscanf(fitxer, "%f", &students[i].report);
fscanf(fitxer, "%s", buffer);
fscanf(fitxer, "%f", &students[i].final_exam);
n_students++;
fscanf(fitxer, "%s", students[i].first_name);
}
fclose(fitxer);
}
return n_students;
}
void computeGrades(Student students[], int n_students) {
int i = 0;
int j = 0;
float average = 0;
float kg = 0;
float pg = 0;
for (i = 0; i < n_students; i++) {
average = 0;
kg = 0;
pg = 0;
for (j = 0; j < 10; j++) {
average += students[i].CA[j];
}
average /= 10;
pg = students[i].Project[0] * 0.3 + students[i].Project[1] * 0.3 +
students[i].Project[0] * 0.3 + students[i].report * 0.1;
kg = 0.7 * students[i].final_exam + 0.3 * average;
if (students[i].final_exam > kg) {
kg = students[i].final_exam;
}
students[i].sem_grade = 0.5 * kg + 0.5 * pg;
}
}
void save(Student students[], int n_students) {
FILE *fitxer = NULL;
int i = 0;
fitxer = fopen("students.bin", "wb");
if (NULL != fitxer) {
for (i = 0; i < n_students; i++) {
fwrite(&students[i], sizeof(Student), 1, fitxer);
}
}
fclose(fitxer);
}
void updateFile() {
Student student;
FILE *fitxer = NULL;
int i = 1;
char filename[MAX_STR];
strcpy(filename, "students.bin");
fitxer = fopen(filename, "rb+");
if (NULL != fitxer) {
fread(&student, sizeof(Student), 1, fitxer);
while (!feof(fitxer)) {
fseek(fitxer, i * sizeof(Student), SEEK_SET);
if ((5 <= student.sem_grade) && (4 > student.final_exam)){
student.sem_grade = 4;
}
fseek(fitxer, i * sizeof(Student), SEEK_SET);
fwrite(&student, i - 1 * sizeof(student), 1, fitxer);
i++;
fread(&student, sizeof(Student), 1, fitxer);
}
} else {
printf("error");
}
}
I think my the problem is in the function loadGrades()
, somehow I'm only storing the last student in the file.