/** * File: keskmineHinne.c * Author: Rainer Liis * Created: 19.02.2018 * Last edit: 20.02.2018 * * Description: The program scans in the students and their grades, * finds the best and the worst. */ #include <stdio.h> // print, scan #include <string.h> // strcpy, strcmp #include "struktuur.h" // holds the structs // counts the rows in the file int numberofRows (); // scans in the data from the file void readStudents (Stud *to_be_graded); // filters out students with unapplicable grades int sieve (Stud *to_be_graded, Filtered *applicable, int n, char DVW); // sorts by name void sortbyName (Filtered *applicable, int applicable_amount, char DVW); // makes a sorted list int list (Filtered *applicable, int , Avg *student_list, char DVW); // calculates each student's average void average (Avg *student_list, Filtered *applicable, int applicable_amount, int student_amount, char DVW); // sorts by grade void sortbyAverage (Avg *student_list, int student_amount, char DVW); // determines who gets the money and who gets the bill void money (Avg *student_list, int student_amount); // outputs bills into file void bill (Avg *student_list, int student_amount); int main (void) { char DVW; // var to hold the answer printf ("Print all or silent? [p/s]"); do // only accepts s or p { scanf ("%c", &DVW); // determines whether functions print results or not } while (DVW != 'p' && DVW != 's'); printf ("\n\n"); int n; n = numberofRows(); // counts how many rows the file contains Stud to_be_graded[n]; // var to hold first scan results Filtered applicable[n]; // var to hold applicable Avg student_list[n]; // var to hold each student and their avg grade int applicable_amount; // nr of applicable elements int student_amount; // nr of students readStudents(to_be_graded); printf ("\n\n"); applicable_amount = sieve (to_be_graded, applicable, n, DVW); sortbyName (applicable, applicable_amount, DVW); student_amount = list (applicable, applicable_amount, student_list, DVW); average (student_list, applicable, applicable_amount, student_amount, DVW); sortbyAverage (student_list, student_amount, DVW); money (student_list, student_amount); bill (student_list, student_amount); return 0; } int numberofRows() { FILE *data; data = fopen ("andmed.txt", "r"); // opens the file int read = 0; int ch = 0; if (data == NULL) // if file doesn't exist, returns 0 { return 0; } // scans every character, if the char is '\n' then the counter counts up while ((ch = fgetc (data)) != EOF) { if (ch == '\n') { read++; } } fclose (data); // closes the file return read; // returns the nr of rows } void readStudents (Stud *to_be_graded) { FILE *data; data = fopen ("andmed.txt", "r"); // opens the file int i = 0; // reads in the data from the file while (fscanf (data, "%s %s %d", to_be_graded[i].name, to_be_graded[i].subj, &to_be_graded[i].grade) != EOF) { // prints the data to the screen printf ("%d. %s, %s, %d\n", i+1, to_be_graded[i].name, to_be_graded[i].subj, to_be_graded[i].grade); i++; } fclose (data); // closes the file } int sieve (Stud *to_be_graded, Filtered *applicable, int n, char DVW) { int i; int j = 0; // if the grade is between 0 and 5, then copy row to applicable for (i = 0; i < n; i++) { if (to_be_graded[i].grade >= 0 && to_be_graded[i].grade <= 5) { strcpy (applicable[j].name, to_be_graded[i].name); applicable[j].grade = to_be_graded[i].grade; j++; } } // if the input character is p, it prints the result if (DVW == 112) // 112 is the ascii value of 'p' { for (i = 0; i < j; i++) { printf ("%d, %s, %d\n", i+1, applicable[i].name, applicable[i].grade); } printf ("\n\n"); } return j; // returns nr of applicable rows } void sortbyName (Filtered *applicable, int applicable_amount, char DVW) { int i; int j; Filtered temp; // sorts applicable alphabetically for (i = 0; i < applicable_amount; i++) { for (j = 1; j < applicable_amount; j++) { if (strcmp (applicable[j-1].name, applicable[j].name) > 0) { temp.grade = applicable[j-1].grade; strcpy (temp.name, applicable[j-1].name); applicable[j-1].grade = applicable[j].grade; strcpy (applicable[j-1].name, applicable[j].name); applicable[j].grade = temp.grade; strcpy (applicable[j].name, temp.name); } } } // if the input character is p, it prints the result if (DVW == 112) // 112 is the ascii value of 'p' { for (i = 0; i < applicable_amount; i++) { printf ("%d, %s, %d\n", i+1, applicable[i].name, applicable[i].grade); } printf ("\n\n"); } } int list (Filtered *applicable, int applicable_amount, Avg *student_list, char DVW) { int i; int j = 0; // makes a list where each name appears once for (i = 0; i < applicable_amount; i++) { if (strcmp (applicable[i-1].name, applicable[i].name) != 0) { strcpy (student_list[j].name, applicable[i].name); j++; } } // if the input character is p, it prints the result if (DVW == 112) // 112 is the ascii value of 'p' { for (i = 0; i < j; i++) { printf ("%d, %s\n", i+1, student_list[i].name); } printf ("\n\n"); } return j; // returns the nr of students } void average (Avg *student_list, Filtered *applicable, int applicable_amount, int student_amount, char DVW) { int i; int j; int counter = 0; // calculates the average of each student for (i = 0; i < student_amount; i++) { for (j = 0; j < applicable_amount; j++) { if (strcmp (student_list[i].name, applicable[j].name) == 0) { student_list[i].grade += applicable[j].grade; counter++; } } student_list[i].average = (float)student_list[i].grade / (float) counter; counter = 0; } // if the input character is p, it prints the result if (DVW == 112) // 112 is the ascii value of 'p' { for (i = 0; i < student_amount; i++) { printf ("%d, %s, %d, %f\n", i+1, student_list[i].name, student_list[i].grade, student_list[i].average); } printf ("\n\n"); } } void sortbyAverage (Avg *student_list, int student_amount, char DVW) { int i, j; Avg temp; // sorts list by average grade for (i = 0; i < student_amount; i++) { for (j = 1; j < student_amount; j++) { if (student_list[j-1].average < student_list[j].average) { temp = student_list[j-1]; student_list[j-1] = student_list[j]; student_list[j] = temp; } } } // if the input character is p, it prints the result if (DVW == 112) // 112 is the ascii value of 'p' { for (i = 0; i < student_amount; i++) { printf ("%d, %s, %f\n", i+1, student_list[i].name, student_list[i].average); } printf ("\n\n"); } } void money (Avg *student_list, int student_amount) { int i; int counter = 0; // prints the first 3 names printf ("The money goes to: \n"); for (i = 0; i < 3; i++) { printf ("%s, with an average of: %f\n", student_list[i].name, student_list[i].average); } counter = i; // checks if the 4th person from the top has the same average as the 3rd, // if that is true, also prints the 4th student's info and then the 5th and so on do { if (student_list[counter].average == student_list[2].average) { printf ("%s, with an average of: %f\n", student_list[counter].name, student_list[counter].average); counter++; } else { break;// stops the loop, if there is a difference in the average grade }; } while (student_list[i].average == student_list[2].average); printf ("\n\n"); } void bill (Avg *student_list, int student_amount) { int counter = student_amount - 4; int i; FILE *output; output = fopen ("bill.txt", "w"); // opens the output file // prints the last 3 people from student_list to the output file printf ("The bills go to: \n"); fprintf (output, "The bills go to: \n"); for (i = student_amount - 3; i < student_amount; i++) { printf ("%s, with an average of: %f\n", student_list[i].name, student_list[i].average); fprintf (output, "%s, with an average of: %.2f\n", student_list[i].name, student_list[i].average); } // checks if the 4th person from the bottom has the same average as the 3rd, // if that is true, also prints the 4th student's info and then the 5th and so on do { if (student_list[counter].average == student_list[i - 3].average) { printf ("%s, with an average of: %f\n", student_list[counter].name, student_list[counter].average); fprintf (output, "%s, with an average of: %f\n", student_list[counter].name, student_list[counter].average); counter--; } else { break; // stops the loop, if there is a difference in the average grade }; } while (student_list[counter].average == student_list[i - 3].average); fclose (output); // closes the file }