UsSe3wa

C mess assig

Oct 2nd, 2024
24
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 14.36 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <ctype.h>
  5. // ^ libraries for lazy ^
  6.  
  7. // macros for numbers
  8. #define PEOPLE 1000
  9. #define EXAMS 500
  10. #define GRADES 1000
  11.  
  12. // list of shortcut errors for ffunc error handler
  13. enum ERR {
  14.     NON,
  15.     E_EXAM,
  16.     E_EXAM_ID,
  17.     E_STUD,
  18.     E_STUD_ID,
  19.     E_GRADE,
  20.     E_DURATION,
  21.     E_SOFTWARE,
  22.     E_EXAM_TYPE,
  23.     E_FAC,
  24.     E_NAME
  25. };
  26.  
  27. // structers directly from task
  28. enum ExamType {
  29.     WRITTEN,
  30.     DIGITAL,
  31.     WRONG
  32. };
  33.  
  34. union ExamInfo {
  35.     short duration; // 40-180 int
  36.     char software[20]; // 2-20 String
  37. };
  38.  
  39. struct Grade {
  40.     short exam_id;
  41.     short grade;
  42. };
  43.  
  44. // grades field for simpler access
  45. struct Student {
  46.     short stud_id; // 1-500 Integer
  47.     char name[20]; // 1-20 String
  48.     char faculty[30]; // 4-30 String
  49.     struct Grade* grades;
  50. };
  51.  
  52. struct Exam {
  53.     short exam_id; // 0-1000 Integer
  54.     enum ExamType exam_type; // enum
  55.     union ExamInfo exam_info; // Union
  56. };
  57.  
  58. // just Prototypes, more readable
  59. void ffunc(FILE*, enum ERR);
  60. struct Student* ADD_STUDENT(FILE*, int, char*, char*);
  61. struct Exam* ADD_EXAM(FILE*, int, enum ExamType, union ExamInfo);
  62. void ADD_GRADE(FILE*, int, int, int);
  63. void UPDATE_EXAM(FILE*, short, enum ExamType, union ExamInfo);
  64. void UPDATE_GRADE(FILE*, short, short, short);
  65. void SEARCH_STUDENT(FILE*, short);
  66. void SEARCH_GRADE(FILE*, short, short);
  67. void DELETE_STUDENT(FILE*, short);
  68. void LIST_ALL_STUDENTS(FILE*);
  69.  
  70. // Global Vars for access
  71. struct Student* students;
  72. short cnt_stud = 0;
  73. struct Exam* exams;
  74. short cnt_exam = 0;
  75. struct Grade* grades;
  76. short cnt_grade = 0;
  77.  
  78.  
  79. // its really hard to comment
  80. // in main body every function in case first argument is proper command
  81. int main() {
  82.     students = (struct Student*)malloc(PEOPLE * sizeof(struct Student));
  83.     exams = (struct Exam*)malloc(EXAMS * sizeof(struct Exam));
  84.     grades = (struct Grade*)malloc(GRADES * sizeof(struct Grade));
  85.  
  86.     FILE* in = fopen("input.txt", "r");
  87.     FILE* out = fopen("output.txt", "w");
  88.  
  89.     char line[100], command[20];
  90.     while (fgets(line, sizeof(line), in)) {
  91.         sscanf(line, "%s", command);
  92.        
  93.         if (strcmp(command, "ADD_STUDENT") == 0) {
  94.             int stud_id;
  95.             char name[20], faculty[30];
  96.             sscanf(line, "%*s %d %s %s", &stud_id, name, faculty); // Skip in sscanf
  97.             ADD_STUDENT(out, stud_id, name, faculty);
  98.         }
  99.         else if (strcmp(command, "ADD_EXAM") == 0) {
  100.             int exam_id;
  101.             char exam_type_str[10], exam_info[20];
  102.             enum ExamType exam_type;
  103.             union ExamInfo exam_info_union;
  104.  
  105.             sscanf(line, "%*s %d %s %s", &exam_id, exam_type_str, exam_info);
  106.             if (strcmp(exam_type_str, "WRITTEN") == 0) {
  107.                 exam_type = WRITTEN;
  108.                 exam_info_union.duration = atoi(exam_info); // Assign duration as an integer
  109.             } else if (strcmp(exam_type_str, "DIGITAL") == 0) {
  110.                 exam_type = DIGITAL;
  111.                 strncpy(exam_info_union.software, exam_info, 20); // Assign software as a string
  112.             } else {
  113.                 ffunc(out, E_EXAM_TYPE);
  114.                 continue;
  115.             }
  116.             ADD_EXAM(out, exam_id, exam_type, exam_info_union);
  117.         }
  118.  
  119.         else if (strcmp(command, "ADD_GRADE") == 0) {
  120.             int exam_id, stud_id, grade;
  121.             sscanf(line, "%*s %d %d %d", &exam_id, &stud_id, &grade);
  122.             ADD_GRADE(out, exam_id, stud_id, grade);
  123.         }
  124.         else if (strcmp(command, "SEARCH_STUDENT") == 0) {
  125.             int stud_id;
  126.             sscanf(line, "%*s %d", &stud_id);
  127.             SEARCH_STUDENT(out, stud_id);
  128.         }
  129.         else if (strcmp(command, "SEARCH_GRADE") == 0) {
  130.             int exam_id, stud_id;
  131.             sscanf(line, "%*s %d %d", &exam_id, &stud_id);
  132.             SEARCH_GRADE(out, exam_id, stud_id);
  133.         }
  134.         else if (strcmp(command, "UPDATE_EXAM") == 0) {
  135.             int exam_id;
  136.             char exam_type_str[10], exam_info[20];
  137.             enum ExamType new_exam_type;
  138.             union ExamInfo new_exam_info;
  139.  
  140.             sscanf(line, "%*s %d %s %s", &exam_id, exam_type_str, exam_info);
  141.             if (strcmp(exam_type_str, "WRITTEN") == 0) {
  142.                 new_exam_type = WRITTEN;
  143.                 new_exam_info.duration = atoi(exam_info);
  144.             } else if (strcmp(exam_type_str, "DIGITAL") == 0) {
  145.                 new_exam_type = DIGITAL;
  146.                 strncpy(new_exam_info.software, exam_info, 20);
  147.             } else {
  148.                 ffunc(out, E_EXAM_TYPE);
  149.                 continue;
  150.             }
  151.             UPDATE_EXAM(out, exam_id, new_exam_type, new_exam_info);
  152.         }
  153.         else if (strcmp(command, "UPDATE_GRADE") == 0) {
  154.             int exam_id, stud_id, new_grade;
  155.             sscanf(line, "%*s %d %d %d", &exam_id, &stud_id, &new_grade);
  156.             UPDATE_GRADE(out, exam_id, stud_id, new_grade);
  157.         }
  158.         else if (strcmp(command, "LIST_ALL_STUDENTS") == 0) {
  159.             LIST_ALL_STUDENTS(out);
  160.         }
  161.         else if (strcmp(command, "DELETE_STUDENT") == 0) {
  162.             int stud_id;
  163.             sscanf(line, "%*s %d", &stud_id);
  164.             DELETE_STUDENT(out, stud_id);
  165.         }
  166.         else if (strcmp(command, "END") == 0) {
  167.             break;  // Exit the loop
  168.         }
  169.     }
  170.  
  171.     // deallocate
  172.     fclose(in);
  173.     fclose(out);
  174.     free(students);
  175.     free(exams);
  176.     free(grades);
  177.  
  178.     return 0;
  179. }
  180.  
  181. // full list for Error Handling
  182. void ffunc(FILE* out, enum ERR err) {
  183.     switch (err) {
  184.         case E_EXAM: fprintf(out, "Exam not found\n"); fflush(out); break;
  185.         case E_EXAM_ID: fprintf(out, "Invalid exam id\n"); fflush(out); break;
  186.         case E_STUD: fprintf(out, "Student not found\n"); fflush(out); break;
  187.         case E_STUD_ID: fprintf(out, "Invalid student id\n"); fflush(out); break;
  188.         case E_GRADE: fprintf(out, "Invalid grade\n"); fflush(out); break;
  189.         case E_DURATION: fprintf(out, "Invalid duration\n"); fflush(out); break;
  190.         case E_SOFTWARE: fprintf(out, "Invalid software\n"); fflush(out); break;
  191.         case E_EXAM_TYPE: fprintf(out, "Invalid exam type\n"); fflush(out); break;
  192.         case E_FAC: fprintf(out, "Invalid faculty\n"); fflush(out); break;
  193.         case E_NAME: fprintf(out, "Invalid name\n"); fflush(out); break;
  194.         default: break;
  195.     }
  196. }
  197.  
  198. // constructor
  199. struct Student* ADD_STUDENT(FILE* out, int stud_id, char* name, char* faculty) {
  200.     // if: check isvalid for diffrent cases
  201.     if (stud_id > 999 || stud_id < 1) {
  202.         ffunc(out, E_STUD_ID);
  203.         return NULL;
  204.     }
  205.     if (students[stud_id].stud_id != 0) {
  206.         fprintf(out, "Student: %d already exists\n", stud_id);
  207.         fflush(out);
  208.         return NULL;
  209.     }
  210.     short len = strlen(name);
  211.     if (len > 19 || len < 2) {
  212.         ffunc(out, E_NAME);
  213.         return NULL;
  214.     }
  215.     int flag = 0;
  216.     for (int i=0; i<strlen(name); i++) {
  217.         if (!isalpha(name[i]))
  218.             flag = 1;
  219.     }
  220.     if (flag) {
  221.         ffunc(out, E_NAME);
  222.         return NULL;
  223.     }
  224.     len = strlen(faculty);
  225.     if (len > 29 || len < 5) {
  226.         ffunc(out, E_FAC);
  227.         return NULL;
  228.     }
  229.     flag = 0;
  230.     for (int i=0; i<strlen(faculty); i++) {
  231.         if (!isalpha(faculty[i]))
  232.             flag = 1;
  233.     }
  234.     if (flag) {
  235.         ffunc(out, E_FAC);
  236.         return NULL;
  237.     }
  238.     // assign
  239.     students[stud_id].stud_id = stud_id;
  240.     strcpy(students[stud_id].name, name);
  241.     strcpy(students[stud_id].faculty, faculty);
  242.     students[stud_id].grades = malloc(10 * sizeof(struct Grade));
  243.     fprintf(out, "Student: %d added\n", stud_id);
  244.     fflush(out);
  245.     cnt_stud++;
  246.     // oop; return struct
  247.     return &students[stud_id];
  248. }
  249.  
  250. // constuctor
  251. struct Exam* ADD_EXAM(FILE* out, int exam_id, enum ExamType exam_type, union ExamInfo exam_info) {
  252.     // basic if checker
  253.     if (exam_id > 499 || exam_id < 1) {
  254.         ffunc(out, E_EXAM_ID);
  255.         return NULL;
  256.     }
  257.     if (exams[exam_id].exam_id != 0) {
  258.         fprintf(out, "Exam: %d already exists\n", exam_id);
  259.         fflush(out);
  260.         return NULL;
  261.     }
  262.  
  263.     // isvalid for written
  264.     if (exam_type == WRITTEN) {
  265.         if (exam_info.duration < 40 || exam_info.duration > 180) {
  266.             ffunc(out, E_DURATION);
  267.             return NULL;
  268.         }
  269.         // Assign the exam details
  270.         exams[exam_id].exam_type = WRITTEN;
  271.         exams[exam_id].exam_info.duration = exam_info.duration;
  272.     }
  273.     // isvalid for digital
  274.     else if (exam_type == DIGITAL) {
  275.         short len = strlen(exam_info.software);
  276.         if (len < 2 || len > 19) {
  277.             ffunc(out, E_SOFTWARE);
  278.             return NULL;
  279.         }
  280.         int flag = 0;
  281.         for (int i=0; i<len; i++) {
  282.             if (!isalpha(exam_info.software[i]))
  283.                 flag = 1;
  284.         }
  285.         if (flag) {
  286.             ffunc(out, E_SOFTWARE);
  287.             return NULL;
  288.         }
  289.         // assign
  290.         exams[exam_id].exam_type = DIGITAL;
  291.         strncpy(exams[exam_id].exam_info.software, exam_info.software, 20);
  292.     }
  293.     else {
  294.         ffunc(out, E_EXAM_TYPE);
  295.         return NULL;
  296.     }
  297.     // assign
  298.     exams[exam_id].exam_id = exam_id; // Set the exam_id
  299.     fprintf(out, "Exam: %d added\n", exam_id);
  300.     fflush(out);
  301.     cnt_exam++;
  302.  
  303.     return &exams[exam_id];
  304. }
  305.  
  306. // constructor
  307. void ADD_GRADE(FILE* out, int exam_id, int stud_id, int grade) {
  308.     // if validation
  309.     if (exam_id < 1 || exam_id > 499) {
  310.         ffunc(out, E_EXAM_ID);
  311.         return;
  312.     }
  313.     if (exams[exam_id].exam_id == 0) {
  314.         ffunc(out, E_EXAM);
  315.         return;
  316.     }
  317.     if (stud_id > 999 || stud_id < 1) {
  318.         ffunc(out, E_STUD_ID);
  319.         return;
  320.     }
  321.     if (students[stud_id].stud_id == 0) {
  322.         ffunc(out, E_STUD);
  323.         return;
  324.     }
  325.     if (grade < 0 || grade > 100) {
  326.         ffunc(out, E_GRADE);
  327.         return;
  328.     }
  329.     // assign
  330.     grades[cnt_grade].exam_id = exam_id;
  331.     grades[cnt_grade].grade = grade;
  332.     students[stud_id].grades[cnt_grade] = grades[cnt_grade];
  333.     cnt_grade++;
  334.    
  335.     fprintf(out, "Grade %d added for the student: %d\n", grade, stud_id);
  336. }
  337.  
  338. void UPDATE_EXAM(FILE* out, short exam_id, enum ExamType new_exam_type, union ExamInfo new_exam_info) {
  339.     // some validation
  340.     if (exam_id < 1 || exam_id > 499 || exams[exam_id].exam_id == 0) {
  341.         ffunc(out, E_EXAM_ID);
  342.         return;
  343.     }
  344.     if (new_exam_type == WRITTEN) {
  345.         if (new_exam_info.duration < 40 || new_exam_info.duration > 180) {
  346.             ffunc(out, E_DURATION);
  347.             return;
  348.         }
  349.     } else if (new_exam_type == DIGITAL) {
  350.         short len = strlen(new_exam_info.software);
  351.         if (len < 2 || len > 19) {
  352.             ffunc(out, E_SOFTWARE);
  353.             return;
  354.         }
  355.         int flag = 0;
  356.         for (int i=0; i<len; i++) {
  357.             if (!isalpha(new_exam_info.software[i]))
  358.                 flag = 1;
  359.         }
  360.         if (flag) {
  361.             ffunc(out, E_SOFTWARE);
  362.             return;
  363.         }
  364.     } else if (new_exam_type == WRONG) {
  365.         ffunc(out, E_EXAM_TYPE);
  366.         return;
  367.     }
  368.     // assign
  369.     exams[exam_id].exam_type = new_exam_type;
  370.     exams[exam_id].exam_info = new_exam_info;
  371.     fprintf(out, "Exam: %d updated\n", exam_id);
  372.     fflush(out);
  373. }
  374.  
  375. void UPDATE_GRADE(FILE* out, short exam_id, short stud_id, short new_grade) {
  376.     // valid grade
  377.     if (new_grade > 100 || new_grade < 0) {
  378.         ffunc(out, E_GRADE);
  379.         return;
  380.     }
  381.     // find place to grade
  382.     int i = 0;
  383.     for (i = 0; i < cnt_grade; i++) {
  384.         if (grades[i].exam_id == exam_id && students[stud_id].stud_id == stud_id) {
  385.             grades[i].grade = new_grade;
  386.             fprintf(out, "Grade %d updated for the student: %d\n", new_grade, stud_id);
  387.             fflush(out);
  388.             return;
  389.         }
  390.     }
  391.     // no grade
  392.     ffunc(out, E_GRADE);
  393. }
  394.  
  395.  
  396. void SEARCH_STUDENT(FILE* out, short stud_id) {
  397.     // error handling with if
  398.     if (stud_id > 999 || stud_id < 1) {
  399.         ffunc(out, E_STUD_ID);
  400.         return;
  401.     }
  402.     if (students[stud_id].stud_id == 0) {
  403.         ffunc(out, E_STUD);
  404.         return;
  405.     }
  406.     fprintf(out, "ID: %d, Name: %s, Faculty: %s\n", students[stud_id].stud_id, students[stud_id].name, students[stud_id].faculty);
  407.     fflush(out);
  408. }
  409.  
  410. void SEARCH_GRADE(FILE* out, short exam_id, short stud_id) {
  411.     // again checking conditions
  412.     if (exam_id < 1 || exam_id > 499 || exams[exam_id].exam_id == 0) {
  413.         ffunc(out, E_EXAM_ID);
  414.         return;
  415.     }
  416.     if (stud_id > 999 || stud_id < 1 || students[stud_id].stud_id == 0) {
  417.         ffunc(out, E_STUD);
  418.         return;
  419.     }
  420.     // Searching for grades
  421.     for (int i = 0; i < cnt_grade; i++) {
  422.         if (grades[i].exam_id == exam_id && students[stud_id].stud_id == stud_id) {
  423.             if (exams[exam_id].exam_type == WRITTEN) {
  424.                 fprintf(out, "Exam: %d, Student: %d, Name: %s, Grade: %d, Type: %s, Info: %d\n",
  425.                     exam_id, stud_id, students[stud_id].name, grades[i].grade, "WRITTEN", exams[exam_id].exam_info.duration);
  426.                 fflush(out);
  427.             }
  428.             else {
  429.                 fprintf(out, "Exam: %d, Student: %d, Name: %s, Grade: %d, Type: %s, Info: %s\n",
  430.                     exam_id, stud_id, students[stud_id].name, grades[i].grade, "DIGITAL", exams[exam_id].exam_info.software);
  431.                 fflush(out);
  432.             }
  433.             return;
  434.         }
  435.     }
  436.  
  437.     // no grade again
  438.     ffunc(out, E_GRADE);
  439. }
  440.  
  441. // destructor
  442. void DELETE_STUDENT(FILE* out, short stud_id) {
  443.     if (stud_id < 1 || stud_id > 999 || students[stud_id].stud_id == 0) {
  444.         ffunc(out, E_STUD);
  445.         return;
  446.     }
  447.  
  448.     // deallocate
  449.     free(students[stud_id].grades);
  450.  
  451.     // Reset cells
  452.     students[stud_id].stud_id = 0;
  453.     memset(students[stud_id].name, 0, sizeof(students[stud_id].name));
  454.     memset(students[stud_id].faculty, 0, sizeof(students[stud_id].faculty));
  455.  
  456.     fprintf(out, "Student: %d deleted\n", stud_id);
  457.     fflush(out);
  458.     cnt_stud--;
  459. }
  460.  
  461. // nothing but print
  462. void LIST_ALL_STUDENTS(FILE* out) {
  463.     for (int i = 0; i < PEOPLE; i++) {
  464.         if (students[i].stud_id != 0) {
  465.             fprintf(out, "ID: %d, Name: %s, Faculty: %s\n",
  466.                     students[i].stud_id, students[i].name, students[i].faculty);
  467.             fflush(out);
  468.         }
  469.     }
  470. }
  471.  
Add Comment
Please, Sign In to add comment