
// PROGRAM LISTING

#include <stdlib.h> // necessary include files
#include <stdio.h>
#include <string.h>

// *** DEFINE DATA STRUCTURES

struct studentEntry 
    {
    char name[40];
    float grade;
    } student [100];    // student is an array of studentEntry elements

char name[100][40]; //name is an array of 40-character elements
float grade[100];   //grade is an array of float elements

// *** PROTOTYPE QSORT() COMPARE FUNCTIONS FOR EACH DATA TYPE

int nameComp(const void *, const void *);
int gradeComp(const void *, const void *);
int structComp(const void *, const void *);

// *** BEGIN MAIN PROGRAM

int main( int argc, char *argv[] ) 
     {
     // read student file (however it must be done)
     FILE *studentFile;
     if(!(studentFile=fopen(argv[1],"rt"))) 
          {
          printf("error opening input student file\n");
          exit(1);
          }
     
     // read studentFile
     char line[100];
     char tmpName[40];
     float tmpGrade;
     for( int i=0; fgets(line, 100, studentFile); i++ ) 
          {
          sscanf(line,"%s %f", tmpName, &tmpGrade);
          grade[i]=student[i].grade=tmpGrade;
          strcpy(name[i],strcpy(student[i].name,tmpName));
         }

     fclose(studentFile);

     // *** SORT each list using its sort function
     qsort((void *)student,i,sizeof(studentEntry),structComp);
     qsort((void *)name,i,sizeof(char)*40,nameComp);
     qsort((void *)grade,i,sizeof(float),gradeComp);

     // print results
     for( int j=0; j<i; j++ )
          printf ("%20s  %6.2f     %20s %6.2f\n", 
              student[j].name,student[j].grade,name[j],grade[j]);

     }

// *** COMPARE FUNCTION DEFINITIONS
// *** Notice the header.  In the main body of the function the
// *** arguments are cast to what they represent.  The user must
// *** do this1

int name Comp(const void *a, const void *b) 
     {
     return strcmp((char *)a,(char *)b);
     }

int gradeComp(const void *a, const void *b) 
     {
     if(*((float *)a)<*((float *)b)) return -1;
     if(*((float *)a)>*((float *)b)) return 1;
     else return 0;
     }

int structComp(const void *a, const void *b) 
     {
     if(((student Entry *)a)->grade<((studentEntry *)b)->grade) 
         return -1;
     if(((studentEntry *)a)->grade>((studentEntry *)b)->grade) 
         return 1;
     return 0;
     }

