#include #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_Node *prev_node = NULL; Sllist_Node *current_node; Person *current_person; if (sll_empty(student_list)) { sll_append(student_list, p); return; } for (current_node = sll_first(student_list); current_node != NULL; current_node = sll_next(current_node)) { current_person = (Person *)sll_val(current_node); if (p->score < current_person->score) break; else prev_node = current_node; } if (prev_node == NULL) sll_prepend(student_list, p); else sll_insert_after(student_list, prev_node, p); } /* Return the average score in a list of people */ double return_avg(Sllist *d) { Sllist_Node *tmp; double n, t; Person *p; t = 0.0; n = 0; for (tmp = sll_first(d); tmp != NULL; tmp = sll_next(tmp)) { p = (Person *) sll_val(tmp); 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_Node *tmp; double diff; Person *p; for (tmp = sll_first(d); tmp != NULL; tmp = sll_next(tmp)) { p = (Person *) sll_val(tmp); 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; 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"); } /* free the lists */ free_sllist(ugrad); free_sllist(grad); }