+1 (315) 557-6473 

Sorting algorithm problem in C

The code below demonstrates the implementation of sorting and merging in C.

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);
}