My C code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_GRADES 100
#define MAX_SUBJECTS 100
// struct to store subject data
typedef struct
{
char code[50];
char subjectName[50];
float cr;
float grade;
} Subject;
// struct to store grade data
typedef struct
{
char grade[50];
Subject subjects[MAX_SUBJECTS];
int numSubjects;
float avgGrade;
} GradeData;
// struct to store subject group data
typedef struct
{
char subjectGroup[3];
float totalGrade;
int count;
} SubjectGroup;
int main()
{
// change file name here
char filename[] = "grades.csv";
FILE *file, *outputFile;
char line[100];
GradeData grades[MAX_GRADES];
int numGrades = 0;
float totalGradeSum = 0;
int totalNumSubjects = 0;
SubjectGroup subjectGroups[MAX_SUBJECTS];
int numSubjectGroups = 0;
int isFirstLine = 1;
file = fopen(filename, "r");
// in case file does not exist
if (file == NULL)
{
perror("Error opening file");
return -1;
}
// create output file
outputFile = fopen("output.csv", "w");
// in case file does not exist
if (outputFile == NULL)
{
perror("Error creating output file");
return -1;
}
// read file line by line
while (fgets(line, sizeof(line), file)) {
if (isFirstLine) {
isFirstLine = 0;
continue;
}
if (line[0] != ',') {
if (line[0] != '\n') {
sscanf(line, "%[^,],", grades[numGrades].grade);
grades[numGrades].numSubjects = 0;
numGrades++;
}
} else {
Subject newSubject;
sscanf(line, ",%[^,],%[^,],%f,%f", newSubject.code, newSubject.subjectName, &newSubject.cr, &newSubject.grade);
if (grades[numGrades - 1].numSubjects < MAX_SUBJECTS) {
strcpy(grades[numGrades - 1].subjects[grades[numGrades - 1].numSubjects].code, newSubject.code);
strcpy(grades[numGrades - 1].subjects[grades[numGrades - 1].numSubjects].subjectName, newSubject.subjectName);
grades[numGrades - 1].subjects[grades[numGrades - 1].numSubjects].cr = newSubject.cr;
grades[numGrades - 1].subjects[grades[numGrades - 1].numSubjects].grade = newSubject.grade;
grades[numGrades - 1].numSubjects++;
totalGradeSum += newSubject.grade;
totalNumSubjects++;
// Calculate subject group averages
char subjectGroup[3];
strncpy(subjectGroup, newSubject.code, 2); // get first 2 characters of subject code
subjectGroup[2] = '\0'; // add null terminator
int found = 0;
for (int i = 0; i < numSubjectGroups; i++) // check if subject group already exists
{
if (strcmp(subjectGroup, subjectGroups[i].subjectGroup) == 0) // if subject group exists
{
// add grade to total grade and increment count
subjectGroups[i].totalGrade += newSubject.grade; // add grade to total grade
subjectGroups[i].count++; // increment count
found = 1; // set found to true
break;
}
}
if (!found) // if subject group does not exist
{
strcpy(subjectGroups[numSubjectGroups].subjectGroup, subjectGroup); // copy subject group to subject group data
subjectGroups[numSubjectGroups].totalGrade = newSubject.grade; // set total grade to grade
subjectGroups[numSubjectGroups].count = 1; // set count to 1
numSubjectGroups++; // increment number of subject groups
}
}
}
// calculate average grade for each grade
for (int i = 0; i < numGrades; i++)
{
// calculate average grade
float sum = 0;
for (int j = 0; j < grades[i].numSubjects; j++)
{
sum += grades[i].subjects[j].grade; // add grade to sum
}
grades[i].avgGrade = sum / grades[i].numSubjects; // calculate average grade
}
// write to output file
// write grade data
fprintf(outputFile, "Grade,Average Grade\n"); // write header
for (int i = 0; i < numGrades; i++) // write grade data
{
fprintf(outputFile, "%s,%.2f\n", grades[i].grade, grades[i].avgGrade);
}
// write overall average grade
fprintf(outputFile, "Overall Average Grade,%.2f\n",
totalGradeSum / totalNumSubjects);
// write subject group averages
fprintf(outputFile, "\nSubject Group,Average Grade\n");
for (int i = 0; i < numSubjectGroups; i++) // write subject group data
{
fprintf(outputFile, "%s,%.2f\n", subjectGroups[i].subjectGroup,
subjectGroups[i].totalGrade / subjectGroups[i].count);
}
fclose(file); // close input file
fclose(outputFile); // close output file
return 0;
}
The code read grades.csv
,CODE,Subject NAME,CR,Grade
Grade 10 Term 1,TH31101,Thai Language 1,1.0,1.5
,MA31101,Mathematics 1,1.0,4
,SC30101,Science (Physics),1.0,4
,EN31201,English Reading-Writing 1,1.5,4
,,,,
,,,,
Grade 10 Term 2,TH31102,Thai Language 2,1.0,4
,MA31102,Mathematics 2,1.0,4
,SC30103,Computational Science 1,0.5,3.5
,EN31202,English Reading - Writing 2,1.5,4
But it output is missing first subject in each term
Grade,Average Grade
Grade 10 Term 1,3.72
Grade 10 Term 2,3.88
Overall Average Grade,3.86
Subject Group,Average Grade
MA,3.75
SC,3.83
EN,4.00
I think there is problem that it don't read first subject in each term because I on the same row with term name.
I had try to clone lines that calc data to if condition that true when it is new subject but it doesn't work
If your csv file is always formated this way you just need to read a subject for every line, including the term line.
This will give you the output: