Thread: Help with C program sorting structs

  1. #1
    Registered User
    Join Date
    Dec 2016
    Posts
    1

    Help with C program sorting structs

    I have everything except for the last two prototype functions, I think. Please help.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    
    #define MAX_STUDENTS 20
    #define MAX_LINE 100
    
    
    // field widths
    #define FIRST 7
    #define MIDDLE 1
    #define LAST 9
    #define STREET 16
    #define CITY 11
    #define STATE 2
    #define ZIP 5
    #define AGE 2
    #define GPA 4
    
    
    typedef struct {
        char street[STREET + 1];
        char city[CITY + 1];
        char state[STATE + 1];
        char zip[ZIP + 1];
    } Address;
    
    
    typedef struct {
        char first[FIRST + 1];
        char initial[MIDDLE + 1];
        char last[LAST + 1];
        Address address;
        int age;
        double gpa;
    } Student;
    
    
    // prototypes
    void strsub(char *buffer, char *s, int start, int end);
    int readData(Student students[]);
    void outputData(Student students[], int num);
    void bestGPA(Student students[], int num);
    double averageGPA(Student students[], int num);
    void aboveAverage(Student students[], int num, double avgGPA);
    void youngestBelowAverage(Student students[], int num, double avgGPA);
    void sort(Student students[], int num);
    
    
    // Lab_6.c: Students GPA
    void main(void)
    {
        Student students[MAX_STUDENTS];
        int num;
        double avgGPA;
        
        num = readData(students);
        outputData(students, num);
        bestGPA(students, num);
        avgGPA = averageGPA(students, num);
        aboveAverage(students, num, avgGPA);
        youngestBelowAverage(students, num, avgGPA);
        sort(students, num);
        outputData(students, num);
    }
    
    
    // strsub: copy buffer to s from start for size
    void strsub(char *buffer, char *s, int start, int size)
    {
        int i, j, finish;
        
        i = start;
        j = 0;
        finish = start + size;
        
        while (i < finish)
            s[j++] = buffer[i++];
            
        s[j] = '\0';
    }
    
    
    // readData: read file, populate array of structs, return # of Students
    int readData(Student students[])
    {
        int i = 0;
        char buf[MAX_LINE], temp[20];
        FILE *fp;
        
        if (!(fp = fopen("students.dat", "r"))) {
            puts("File not found.");
            exit(1);
        }
        
        while (!feof(fp)) {
            fgets(buf, MAX_LINE, fp);
            strsub(buf, students[i].first, 0, FIRST);
            strsub(buf, students[i].initial, 8, MIDDLE);
            strsub(buf, students[i].last, 10, LAST);
            strsub(buf, students[i].address.street, 20, STREET);
            strsub(buf, students[i].address.city, 37, CITY);
            strsub(buf, students[i].address.state, 49, STATE);
            strsub(buf, students[i].address.zip, 52, ZIP);
            strsub(buf, temp, 58, AGE);
            students[i].age = atoi(temp);
            strsub(buf, temp, 61, GPA);
            students[i].gpa = atof(temp);
            ++i;
        }
        return i;
    }
    
    
    // outputData: output array of structs in easily read format
    void outputData(Student students[], int num)
    {
        int i;
        
        printf("\nOUTPUT DATA\n");
        printf("-----------\n");
        for (i = 0; i < num; i++) {
            printf("%s ", students[i].first);
            printf("%s ", students[i].initial);
            printf("%s ", students[i].last);
            printf("%s ", students[i].address.street);
            printf("%s ", students[i].address.city);
            printf("%s ", students[i].address.state);
            printf("%s ", students[i].address.zip);
            printf("%d ", students[i].age);
            printf("%.2lf\n", students[i].gpa);
        }
    }
    
    
    // bestGPA: print the full name of the student with the best GPA
    void bestGPA(Student students[], int num)
    {
        int i, best;
        
        best = 0;
        
        for (i = 0; i < num; i++)
            if (students[i].gpa > students[best].gpa)
                best = i;
                
        printf("\nThe student with the best GPA is: %s %s %s\n", students[best].first, students[best].initial, students[best].last);
    }
    
    
    // averageGPA: calculate and print the average GPA
    double averageGPA(Student students[], int num)
    {
        int i;
        double avg;
        
        avg = 0;
        
        for (i = 0; i < num; i++)
            avg += students[i].gpa;
            
        printf("\nThe average GPA of all students is: %.2f\n", avg/num);
        
        return avg/num;     // required to compile
    }
    
    
    // aboveAverage: print the names of all students with GPAs above the average
    void aboveAverage(Student students[], int num, double avgGPA)
    {
        int i;
        
        printf("\nStudents with above average GPA:\n");
        
        for (i = 0; i < num; i++)
            if (students[i].gpa > avgGPA)
                printf("        %s %s %s\n", students[i].first, students[i].initial, students[i].last);
    }
    
    
    // youngestBelowAverage: print the name of the youngest student who has a GPA below average
    void youngestBelowAverage(Student students[], int num, double avgGPA)
    {
        
    }
    
    
    //sort: sort the structures in the array into order from lowest to highest GPA
    void sort(Student students[], int num)
    {
        
    }

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    1. main returns int, not void
    FAQ > main() / void main() / int main() / int main(void) / int main(int argc, char *argv[]) - Cprogramming.com

    2. Your use of feof() is wrong
    FAQ > Why it's bad to use feof() to control a loop - Cprogramming.com

    What you should have is a combined read and test, like so
    Code:
    while (fgets(buf, MAX_LINE, fp) != NULL) {
    The reason is you can read the last byte of the file and feof() will still remain false.
    feof() will only return true AFTER an attempt to read the file has failed.

    > // youngestBelowAverage: print the name of the youngest student who has a GPA below average
    This is basically the same idea as aboveAverage(), with a bit of logic from bestGPA() thrown in.

    > //sort: sort the structures in the array into order from lowest to highest GPA
    Sorting algorithm - Wikipedia
    If you're allowed to use qsort() in stdlib.h, all the hard work is done for you.
    If you want a quick-and-dirty approach, then bubble sort is dead easy to write, so long as you don't get marked down for inefficiency.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Jun 2015
    Posts
    1,640
    You should also check that you don't overflow your array in readData:
    Code:
    while (fgets(...) != NULL) {
        if (i >= MAX_STUDENTS) {
            printf("yikes\n");
            exit(EXIT_FAILURE);
        }
        ...
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Sorting Structs Program Help
    By rb737 in forum C Programming
    Replies: 2
    Last Post: 05-08-2016, 07:21 PM
  2. Sorting a vector of structs....
    By ropitch in forum C++ Programming
    Replies: 7
    Last Post: 07-10-2009, 11:49 PM
  3. Replies: 3
    Last Post: 03-31-2009, 12:34 PM
  4. sorting containers of structs
    By bigSteve in forum C++ Programming
    Replies: 2
    Last Post: 01-06-2004, 02:50 PM
  5. sorting an array of structs
    By singletrackmind in forum C++ Programming
    Replies: 8
    Last Post: 11-13-2001, 03:33 AM

Tags for this Thread