#include #include #include "fields.h" #include "sllist.h" typedef struct { char *fname; char *lname; double score; } Person; /* Insert the new person into the list while maintaining a sorted order. * we need to traverse through the list until we find a node whose name * is alphabetically greater than the inserted name. We then need to * insert the new node *before* the node at which we stopped. This will * require us to keep a pointer to the previous node as well as the * current node, since with a singly linked list we cannot get back * to the previous node from the current node. */ void insert_person(Person *p, Sllist student_list) { Sllist prev_node = student_list; Sllist current_node; Person *current_person; sll_traverse(current_node, student_list) { current_person = (Person *)current_node->val.v; if (strcmp(p->lname, current_person->lname) < 0) break; else prev_node = current_node; } sll_insert_after(prev_node, new_jval_v((void *)p)); } /* Return the average score in a list of people */ double return_avg(Sllist d) { Sllist tmp; double n, t; Person *p; t = 0.0; n = 0; sll_traverse(tmp, d) { p = (Person *) jval_v(tmp->val); t += p->score; n++; } if (n == 0) return (double) 0; return t/n; } /* Print a list of students, plus the difference between each student's score and the average */ print_list(Sllist d, double avg) { Sllist tmp; double diff; Person *p; sll_traverse(tmp, d) { p = (Person *) jval_v(tmp->val); diff = p->score - avg; printf(" %-10s %-10s %5.2lf %6.2lf\n", p->fname, p->lname, p->score, diff); } } /* The main -- read in the students, calculate the averages and print them */ main() { IS is; Sllist grad, ugrad, prev, current; double uavg, gavg; Person *p; /* Create a list of graduate students and a list of undergraduate students. */ grad = new_sllist(); ugrad = new_sllist(); /* Read in the students and put them into either grad or ugrad */ is = new_inputstruct(NULL); while (get_line(is) >= 0) { if (is->NF != 4) { fprintf(stderr, "Line %d: Bad format for grade file\n", is->line); exit(1); } p = (Person *) malloc(sizeof(Person)); p->fname = strdup(is->fields[0]); p->lname = strdup(is->fields[1]); if (sscanf(is->fields[3], "%lf", &p->score) != 1) { fprintf(stderr, "Line %d: Bad format for grade file\n", is->line); exit(1); } if (strcmp(is->fields[2], "U") == 0) { insert_person(p, ugrad); } else if (strcmp(is->fields[2], "G") == 0) { insert_person(p, grad); } else { fprintf(stderr, "Line %d: Bad format for grade file\n", is->line); exit(1); } } /* Print out the undergraduate average and students */ if (!sll_empty(ugrad)) { uavg = return_avg(ugrad); printf("Undergraduates: Average = %5.2lf\n", uavg); print_list(ugrad, uavg); printf("\n"); } /* Print out the graduate average and students */ if (!sll_empty(grad)) { gavg = return_avg(grad); printf("Graduates: Average = %5.2lf\n", gavg); print_list(grad, gavg); printf("\n"); } }