Sorting and Merging Algorithm in C
For this assignment, you have to write a C assignment that will use dynamic memory allocation. Your solution should follow a set of requirements to get credit.#include
#include
#include
// Data type that stores student information
typedef struct student
{
int id;
char *lname;
float *scores;
float std_avg;
} student;
// Data type that stores course information
typedef struct course
{
char *course_name;
int num_sections;
student **sections;
int *num_students;
int *num_scores;
} course;
// Function prototypes
student **read_sections(FILE *fp, int num_students[], int num_scores[], int num_sections);
course *read_courses(FILE *fp, int *num_courses);
void release_sections(student **sections, int num_students[], int num_sections);
void release_courses(course *courses, int num_courses);
void generate_course_report(course *course);
// Start the program
int main(int argc, char *argv[])
{
// Open the file for reading, quit if failed to open file
FILE *fp = fopen("assignment1input.txt", "r");
if (fp == NULL)
{
printf("Failed to open assignment1input.txt\n");
return 0;
}
// Load each test
int test_size;
fscanf(fp, "%d", &test_size);
for (int i = 1; i <= test_size; i++)
{
int num_courses;
course *courses = read_courses(fp, &num_courses);
printf("test case %d\n", i);
// Generate a report for each course
for (int j = 0; j < num_courses; j++)
generate_course_report(&courses[j]);
release_courses(courses, num_courses);
printf("\n");
}
fclose(fp);
return 0;
}
// Load a list of sections where each section has a list of students
student **read_sections(FILE *fp, int num_students[], int num_scores[], int num_sections)
{
student **sections = (student **)malloc(sizeof(student *) * num_sections);
// Load each section from file
for (int i = 0; i < num_sections; i++)
{
// Read how many students and scores are there for the current section
fscanf(fp, "%d %d", &num_students[i], &num_scores[i]);
sections[i] = (student *)malloc(sizeof(student) * num_students[i]);
// Load the students for the current section
for (int j = 0; j < num_students[i]; j++)
{
// Load the name and score for the student to be added to the section
sections[i][j].lname = (char *)malloc(sizeof(char) * 21);
sections[i][j].scores = (float *)malloc(sizeof(float) * num_scores[i]);
fscanf(fp, "%d %s", §ions[i][j].id, sections[i][j].lname);
// Load the scores of this student on this section
for (int k = 0; k < num_scores[i]; k++)
fscanf(fp, "%f", §ions[i][j].scores[k]);
}
}
return sections;
}
// Read an array of courses
course *read_courses(FILE *fp, int *num_courses)
{
// Load each course from file
fscanf(fp, "%d", num_courses);
course *courses = (course *)malloc(sizeof(course) * (*num_courses));
for (int i = 0; i < *num_courses; i++)
{
// Read a name and how many sections are there
courses[i].course_name = (char *)malloc(sizeof(char) * 21);
fscanf(fp, "%s", courses[i].course_name);
fscanf(fp, "%d", &courses[i].num_sections);
// Initialize the slots for sections
courses[i].num_students = (int *)malloc(sizeof(int) * courses[i].num_sections);
courses[i].num_scores = (int *)malloc(sizeof(int) * courses[i].num_sections);
// Read the sections for the course
courses[i].sections = read_sections(fp, courses[i].num_students, courses[i].num_scores, courses[i].num_sections);
}
return courses;
}
// Deallocate the section pointers
void release_sections(student **sections, int num_students[], int num_sections)
{
// For each section deallocate we first deallocate the students
for (int i = 0; i < num_sections; i++)
{
// For each student deallocate the pointers used such as the name and list of scores
for (int j = 0; j < num_students[i]; j++)
{
free(sections[i][j].lname);
free(sections[i][j].scores);
}
// Deallocate student
free(sections[i]);
}
// Deallocate section
free(sections);
}
// Deallocate the courses pointers
void release_courses(course *courses, int num_courses)
{
// Forea ch course deallocate first the sections
for (int i = 0; i < num_courses; i++)
{
release_sections(courses[i].sections, courses[i].num_students, courses[i].num_sections);
// Deallocate the pointers used by current course such as the name, number of students, and
// list of scores
free(courses[i].course_name);
free(courses[i].num_students);
free(courses[i].num_scores);
}
// Deallocate courses
free(courses);
}
// Generate a report about a course as stated in the requiremets
void generate_course_report(course *course)
{
int top_student_id = -1;
char *top_student_name = NULL;
float top_student_average = 0;
float *section_averages = (float *)malloc(sizeof(float) * course->num_sections);
int passers_count = 0;
// For each section find out the average
for (int i = 0; i < course->num_sections; i++)
{
float section_average = 0;
// For each student in a section, found out the average
for (int j = 0; j < course->num_students[i]; j++)
{
float average = 0;
for (int k = 0; k < course->num_scores[i]; k++)
average += course->sections[i][j].scores[k];
average /= course->num_scores[i];
if (average >= 70)
passers_count++;
// Find out the highest student average
if (average > top_student_average)
{
top_student_average = average;
top_student_name = course->sections[i][j].lname;
top_student_id = course->sections[i][j].id;
}
section_average += average;
}
section_averages[i] = section_average / course->num_students[i];
}
// Print report
printf("%s ", course->course_name);
printf("%d ", passers_count);
for (int i = 0; i < course->num_sections; i++)
printf("%.2f ", section_averages[i]);
printf("%d %s %.2f\n", top_student_id, top_student_name, top_student_average);
free(section_averages);
}