Fixed and replace for real test
But not fixed the find failed issue yet Find failed have only one record found, but it's many
This commit is contained in:
parent
52dcaf6fac
commit
657807d6a2
430
real/q1.c
430
real/q1.c
@ -1,7 +1,10 @@
|
|||||||
#include "stdio.h"
|
#include "stdio.h"
|
||||||
#include "stdlib.h"
|
#include "stdlib.h"
|
||||||
|
#include "string.h"
|
||||||
|
|
||||||
#define BUFFER_SIZE 128
|
#define BUFFER_SIZE 128
|
||||||
|
#define MAX_NO_OF_UNITS 4
|
||||||
|
#define NAME_SIZE 20
|
||||||
|
|
||||||
const char *FILE_STUDENT_DATA_PATH = "./students.txt";
|
const char *FILE_STUDENT_DATA_PATH = "./students.txt";
|
||||||
|
|
||||||
@ -15,7 +18,7 @@ struct course_tag
|
|||||||
{
|
{
|
||||||
char course_name[20];
|
char course_name[20];
|
||||||
int no_of_units;
|
int no_of_units;
|
||||||
int marks[4];
|
int marks[MAX_NO_OF_UNITS];
|
||||||
float avg;
|
float avg;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -31,24 +34,30 @@ typedef struct person_tag PERSON;
|
|||||||
typedef struct course_tag COURSE;
|
typedef struct course_tag COURSE;
|
||||||
typedef struct student_tag STUDENT;
|
typedef struct student_tag STUDENT;
|
||||||
|
|
||||||
|
// file function
|
||||||
|
void read_file();
|
||||||
|
|
||||||
|
// util functions
|
||||||
|
void display_menu();
|
||||||
|
void print_welcome();
|
||||||
|
void print_student(STUDENT *student);
|
||||||
|
void release(STUDENT *data);
|
||||||
|
int find_min_in_array(int *array);
|
||||||
|
STUDENT *search_student_by_name_or_id(char search_key[NAME_SIZE]);
|
||||||
|
STUDENT *find_maximum_avg();
|
||||||
|
|
||||||
// core functions
|
// core functions
|
||||||
void display_students();
|
void display_students();
|
||||||
void search_student();
|
void search_student();
|
||||||
void find_maximum();
|
void find_maximum();
|
||||||
void find_failed();
|
void find_failed();
|
||||||
void update_file();
|
void update_file();
|
||||||
void read_file();
|
|
||||||
void quite();
|
void quite();
|
||||||
|
|
||||||
// Linked list functions
|
// Linked list functions
|
||||||
void add_student(char *student_name, char *student_id, char *course_name, int no_of_units, int *marks);
|
void add_student(char student_name[20], char student_id[10], char course_name[20], int no_of_units, int marks[MAX_NO_OF_UNITS]);
|
||||||
int count();
|
int count();
|
||||||
|
|
||||||
// util functions
|
|
||||||
void display_menu();
|
|
||||||
void read_student_to_data();
|
|
||||||
void print_welcome();
|
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
// variable use for menu selected
|
// variable use for menu selected
|
||||||
@ -56,8 +65,12 @@ int main(void)
|
|||||||
|
|
||||||
print_welcome();
|
print_welcome();
|
||||||
|
|
||||||
display_menu();
|
// init the read data from the file
|
||||||
|
read_file();
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
display_menu();
|
||||||
printf("Enter your option: ");
|
printf("Enter your option: ");
|
||||||
scanf("%d", &selected);
|
scanf("%d", &selected);
|
||||||
|
|
||||||
@ -85,6 +98,7 @@ int main(void)
|
|||||||
printf("cannot find your option!");
|
printf("cannot find your option!");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_welcome()
|
void print_welcome()
|
||||||
@ -94,7 +108,44 @@ void print_welcome()
|
|||||||
|
|
||||||
void display_students()
|
void display_students()
|
||||||
{
|
{
|
||||||
read_student_to_data();
|
read_file();
|
||||||
|
|
||||||
|
STUDENT *student = head;
|
||||||
|
|
||||||
|
if (student == NULL)
|
||||||
|
{
|
||||||
|
printf("\nNo student!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
print_student(student);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_student(STUDENT *student)
|
||||||
|
{
|
||||||
|
printf("\n================ Student Details ================\n");
|
||||||
|
while (student != NULL)
|
||||||
|
{
|
||||||
|
printf("\n");
|
||||||
|
printf("Student Name: %s\n", student->student_info.name);
|
||||||
|
printf("Student ID: %s\n", student->student_info.id);
|
||||||
|
printf("Course Name: %s\n", student->course_info.course_name);
|
||||||
|
printf("No of units: %d\n", student->course_info.no_of_units);
|
||||||
|
|
||||||
|
printf("Marks: [ ");
|
||||||
|
for (int i = 0; i < student->course_info.no_of_units; i++)
|
||||||
|
{
|
||||||
|
printf("%d ", student->course_info.marks[i]);
|
||||||
|
}
|
||||||
|
printf("]\n");
|
||||||
|
printf("Avg: %.2f\n", student->course_info.avg);
|
||||||
|
student = student->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
// clean up the memory
|
||||||
|
// after output the data
|
||||||
|
// because we don;t need it anymore after output
|
||||||
|
release(student);
|
||||||
}
|
}
|
||||||
|
|
||||||
void display_menu()
|
void display_menu()
|
||||||
@ -107,20 +158,29 @@ void display_menu()
|
|||||||
printf("(6) Quit program\n\n");
|
printf("(6) Quit program\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_student(char *student_name, char *student_id, char *course_name, int no_of_units, int *marks)
|
void add_student(char student_name[20], char student_id[10], char course_name[20], int no_of_units, int marks[MAX_NO_OF_UNITS])
|
||||||
{
|
{
|
||||||
STUDENT *temp, *iterator;
|
STUDENT *temp, *iterator;
|
||||||
temp = (struct student_tag *)malloc(sizeof(struct student_tag));
|
temp = (struct student_tag *)malloc(sizeof(struct student_tag));
|
||||||
PERSON info = {student_name, student_id};
|
PERSON info;
|
||||||
COURSE course = {course_name, no_of_units, marks};
|
memcpy(info.name, student_name, 20);
|
||||||
int sum = 0;
|
memcpy(info.id, student_id, 10);
|
||||||
|
|
||||||
|
COURSE course;
|
||||||
|
memcpy(course.course_name, course_name, 20);
|
||||||
|
course.no_of_units = no_of_units;
|
||||||
|
// memcpy(course.marks, marks);
|
||||||
|
|
||||||
|
float sum = 0;
|
||||||
for (int i = 0; i < no_of_units; i++)
|
for (int i = 0; i < no_of_units; i++)
|
||||||
{
|
{
|
||||||
|
course.marks[i] = marks[i];
|
||||||
sum += marks[i];
|
sum += marks[i];
|
||||||
}
|
}
|
||||||
course.avg = sum / no_of_units;
|
course.avg = sum / no_of_units;
|
||||||
temp->student_info = info;
|
temp->student_info = info;
|
||||||
temp->course_info = course;
|
temp->course_info = course;
|
||||||
|
|
||||||
// reference in head
|
// reference in head
|
||||||
iterator = head;
|
iterator = head;
|
||||||
|
|
||||||
@ -140,10 +200,256 @@ void add_student(char *student_name, char *student_id, char *course_name, int no
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void read_student_to_data()
|
int count()
|
||||||
{
|
{
|
||||||
// init head to null
|
int n = 1;
|
||||||
head = NULL;
|
STUDENT *temp;
|
||||||
|
temp = head;
|
||||||
|
if (head == NULL)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (temp->next != NULL)
|
||||||
|
{
|
||||||
|
n++;
|
||||||
|
temp = temp->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
void search_student()
|
||||||
|
{
|
||||||
|
char search_key[NAME_SIZE];
|
||||||
|
|
||||||
|
printf("Enter student name or id to search: ");
|
||||||
|
scanf("%s", &search_key);
|
||||||
|
|
||||||
|
STUDENT *found_student = search_student_by_name_or_id(search_key);
|
||||||
|
if (found_student == NULL)
|
||||||
|
{
|
||||||
|
printf("No student found!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
print_student(found_student);
|
||||||
|
}
|
||||||
|
|
||||||
|
STUDENT *search_student_by_name_or_id(char search_key[NAME_SIZE])
|
||||||
|
{
|
||||||
|
// refresh data from file first
|
||||||
|
read_file();
|
||||||
|
|
||||||
|
STUDENT *temp = head;
|
||||||
|
|
||||||
|
while (temp != NULL)
|
||||||
|
{
|
||||||
|
if (strcmp(temp->student_info.name, search_key) == 0 || strcmp(temp->student_info.id, search_key) == 0)
|
||||||
|
{
|
||||||
|
printf("\nSearch found with key: %s\n", search_key);
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
temp = temp->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
STUDENT *find_maximum_avg()
|
||||||
|
{
|
||||||
|
// refresh data from file first
|
||||||
|
read_file();
|
||||||
|
|
||||||
|
STUDENT *temp = head, *max;
|
||||||
|
max = temp->next;
|
||||||
|
|
||||||
|
while (temp != NULL)
|
||||||
|
{
|
||||||
|
if (max == NULL)
|
||||||
|
{
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (max->course_info.avg < temp->course_info.avg)
|
||||||
|
{
|
||||||
|
max = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
temp = temp->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
// release the max next record
|
||||||
|
// set max next element to NULL
|
||||||
|
// because we use only one record
|
||||||
|
release(max->next);
|
||||||
|
max->next = NULL;
|
||||||
|
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
int find_min_in_array(int *array)
|
||||||
|
{
|
||||||
|
if (array == NULL)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int min = array[0];
|
||||||
|
size_t size = sizeof(array) / sizeof(array[0]);
|
||||||
|
|
||||||
|
for (int i = 1; i < size; i++)
|
||||||
|
{
|
||||||
|
if (array[i] < min)
|
||||||
|
{
|
||||||
|
min = array[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ISSUE: can't find all failed students
|
||||||
|
// It's just return one record back
|
||||||
|
STUDENT *find_failed_mark(int upper_mark)
|
||||||
|
{
|
||||||
|
// refresh data from file first
|
||||||
|
read_file();
|
||||||
|
|
||||||
|
STUDENT *temp = head, *failed_students = NULL;
|
||||||
|
|
||||||
|
while (temp != NULL)
|
||||||
|
{
|
||||||
|
int min = find_min_in_array(temp->course_info.marks);
|
||||||
|
if (min < upper_mark)
|
||||||
|
{
|
||||||
|
if (failed_students == NULL)
|
||||||
|
{
|
||||||
|
failed_students = temp;
|
||||||
|
failed_students->next = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (failed_students->next != NULL)
|
||||||
|
{
|
||||||
|
failed_students = failed_students->next;
|
||||||
|
}
|
||||||
|
failed_students->next = temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
temp = temp->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return failed_students;
|
||||||
|
}
|
||||||
|
|
||||||
|
void find_maximum()
|
||||||
|
{
|
||||||
|
// refresh data from file first
|
||||||
|
read_file();
|
||||||
|
|
||||||
|
STUDENT *max_student = find_maximum_avg();
|
||||||
|
if (max_student == NULL)
|
||||||
|
{
|
||||||
|
printf("\nNo maximum student found!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\nFind maximum avg was found with: %0.2f\n", max_student->course_info.avg);
|
||||||
|
print_student(max_student);
|
||||||
|
}
|
||||||
|
|
||||||
|
void find_failed()
|
||||||
|
{
|
||||||
|
int upper_mark = 50;
|
||||||
|
STUDENT *failed_students = find_failed_mark(upper_mark);
|
||||||
|
if (failed_students == NULL)
|
||||||
|
{
|
||||||
|
printf("\nNo failed student found!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\nFind the failed students that at least one mark less than %d\n", upper_mark);
|
||||||
|
print_student(failed_students);
|
||||||
|
}
|
||||||
|
|
||||||
|
void update_file()
|
||||||
|
{
|
||||||
|
FILE *file;
|
||||||
|
file = fopen(FILE_STUDENT_DATA_PATH, "a");
|
||||||
|
|
||||||
|
char name[20];
|
||||||
|
char id[10];
|
||||||
|
char course_name[20];
|
||||||
|
int no_of_units;
|
||||||
|
int marks[MAX_NO_OF_UNITS];
|
||||||
|
|
||||||
|
printf("Enter student name: ");
|
||||||
|
scanf("%s", &name);
|
||||||
|
|
||||||
|
printf("Enter student id: ");
|
||||||
|
scanf("%s", &id);
|
||||||
|
|
||||||
|
printf("Enter course name: ");
|
||||||
|
scanf("%s", &course_name);
|
||||||
|
|
||||||
|
again:
|
||||||
|
printf("Enter no of units: ");
|
||||||
|
scanf("%d", &no_of_units);
|
||||||
|
|
||||||
|
if (no_of_units > MAX_NO_OF_UNITS && no_of_units <= 0)
|
||||||
|
{
|
||||||
|
printf("you cannot input the units bigger than %d or less than 0\n", MAX_NO_OF_UNITS);
|
||||||
|
getchar();
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < no_of_units; i++)
|
||||||
|
{
|
||||||
|
printf("Enter mark[%d]: ", i + 1);
|
||||||
|
scanf("%d", &marks[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count() > 0)
|
||||||
|
{
|
||||||
|
fputs("\n", file);
|
||||||
|
}
|
||||||
|
|
||||||
|
fputs(name, file);
|
||||||
|
fputs("\n", file);
|
||||||
|
fputs(id, file);
|
||||||
|
fputs("\n", file);
|
||||||
|
fputs(course_name, file);
|
||||||
|
fputs("\n", file);
|
||||||
|
fprintf(file, "%d", no_of_units);
|
||||||
|
|
||||||
|
for (int i = 0; i < no_of_units; i++)
|
||||||
|
{
|
||||||
|
fputs("\n", file);
|
||||||
|
fprintf(file, "%d", marks[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(file);
|
||||||
|
|
||||||
|
printf("\nRecord saved successfully!");
|
||||||
|
|
||||||
|
// reload data into linked list again
|
||||||
|
read_file();
|
||||||
|
}
|
||||||
|
|
||||||
|
void read_file()
|
||||||
|
{
|
||||||
|
// release nodes
|
||||||
|
// we need to clean up the memory
|
||||||
|
if (head != NULL)
|
||||||
|
{
|
||||||
|
STUDENT *temp;
|
||||||
|
while (head != NULL)
|
||||||
|
{
|
||||||
|
temp = head;
|
||||||
|
head = head->next;
|
||||||
|
free(temp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FILE *file;
|
FILE *file;
|
||||||
file = fopen(FILE_STUDENT_DATA_PATH, "r");
|
file = fopen(FILE_STUDENT_DATA_PATH, "r");
|
||||||
@ -154,9 +460,9 @@ void read_student_to_data()
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
char student_name[BUFFER_SIZE];
|
char student_name[20];
|
||||||
char student_id[BUFFER_SIZE];
|
char student_id[10];
|
||||||
char course_name[BUFFER_SIZE];
|
char course_name[20];
|
||||||
int no_of_units;
|
int no_of_units;
|
||||||
int marks[4];
|
int marks[4];
|
||||||
|
|
||||||
@ -194,27 +500,15 @@ void read_student_to_data()
|
|||||||
|
|
||||||
course_name[i] = '\0';
|
course_name[i] = '\0';
|
||||||
|
|
||||||
printf("Student Name: %s\n", student_name);
|
|
||||||
printf("Student ID: %s\n", student_id);
|
|
||||||
printf("Course Name: %s\n", course_name);
|
|
||||||
printf("No of units: %s", no);
|
|
||||||
|
|
||||||
no_of_units = atoi(no);
|
no_of_units = atoi(no);
|
||||||
for (int j = 0; j < no_of_units; j++)
|
for (int j = 0; j < no_of_units; j++)
|
||||||
{
|
{
|
||||||
char d[BUFFER_SIZE];
|
char mark[BUFFER_SIZE];
|
||||||
|
|
||||||
fgets(d, sizeof d, file);
|
fgets(mark, sizeof mark, file);
|
||||||
sscanf(d, "%d", &marks[j]);
|
sscanf(mark, "%d", &marks[j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Marks: [ ");
|
|
||||||
for (int x = 0; x < no_of_units; x++)
|
|
||||||
{
|
|
||||||
printf("%d ", marks[x]);
|
|
||||||
}
|
|
||||||
printf("]\n\n");
|
|
||||||
|
|
||||||
// add into linked list
|
// add into linked list
|
||||||
add_student(student_name, student_id, course_name, no_of_units, marks);
|
add_student(student_name, student_id, course_name, no_of_units, marks);
|
||||||
}
|
}
|
||||||
@ -222,54 +516,28 @@ void read_student_to_data()
|
|||||||
fclose(file);
|
fclose(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
int count()
|
|
||||||
{
|
|
||||||
int n = 1;
|
|
||||||
STUDENT *temp;
|
|
||||||
temp = head;
|
|
||||||
if (head == NULL)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (temp->next != NULL)
|
|
||||||
{
|
|
||||||
n++;
|
|
||||||
temp = temp->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
void search_student()
|
|
||||||
{
|
|
||||||
printf("\nNot implement yet!");
|
|
||||||
}
|
|
||||||
|
|
||||||
void find_maximum()
|
|
||||||
{
|
|
||||||
printf("\nNot implement yet!");
|
|
||||||
}
|
|
||||||
|
|
||||||
void find_failed()
|
|
||||||
{
|
|
||||||
printf("\nNot implement yet!");
|
|
||||||
}
|
|
||||||
|
|
||||||
void update_file()
|
|
||||||
{
|
|
||||||
FILE *file;
|
|
||||||
file = fopen(FILE_STUDENT_DATA_PATH, "a");
|
|
||||||
printf("\nNot implement yet!");
|
|
||||||
}
|
|
||||||
|
|
||||||
void read_file()
|
|
||||||
{
|
|
||||||
printf("\nNot implement yet!");
|
|
||||||
}
|
|
||||||
|
|
||||||
void quite()
|
void quite()
|
||||||
{
|
{
|
||||||
printf("\nGoodbye!");
|
printf("\nGoodbye!");
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void release(STUDENT *data)
|
||||||
|
{
|
||||||
|
if (data == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// free the nodes
|
||||||
|
// because it can be use in memory
|
||||||
|
// we need to clear it first
|
||||||
|
// before we re-initailize the new data
|
||||||
|
STUDENT *temp;
|
||||||
|
while (data != NULL)
|
||||||
|
{
|
||||||
|
temp = data;
|
||||||
|
data = data->next;
|
||||||
|
free(temp);
|
||||||
|
}
|
||||||
|
}
|
@ -114,7 +114,7 @@ void display_students()
|
|||||||
|
|
||||||
if (student == NULL)
|
if (student == NULL)
|
||||||
{
|
{
|
||||||
printf("No student!");
|
printf("\nNo student!\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,6 +308,8 @@ int find_min_in_array(int *array)
|
|||||||
return min;
|
return min;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ISSUE: can't find all failed students
|
||||||
|
// It's just return one record back
|
||||||
STUDENT *find_failed_mark(int upper_mark)
|
STUDENT *find_failed_mark(int upper_mark)
|
||||||
{
|
{
|
||||||
// refresh data from file first
|
// refresh data from file first
|
||||||
@ -318,7 +320,6 @@ STUDENT *find_failed_mark(int upper_mark)
|
|||||||
while (temp != NULL)
|
while (temp != NULL)
|
||||||
{
|
{
|
||||||
int min = find_min_in_array(temp->course_info.marks);
|
int min = find_min_in_array(temp->course_info.marks);
|
||||||
|
|
||||||
if (min < upper_mark)
|
if (min < upper_mark)
|
||||||
{
|
{
|
||||||
if (failed_students == NULL)
|
if (failed_students == NULL)
|
||||||
@ -340,6 +341,7 @@ STUDENT *find_failed_mark(int upper_mark)
|
|||||||
|
|
||||||
return failed_students;
|
return failed_students;
|
||||||
}
|
}
|
||||||
|
|
||||||
void find_maximum()
|
void find_maximum()
|
||||||
{
|
{
|
||||||
// refresh data from file first
|
// refresh data from file first
|
||||||
|
Loading…
Reference in New Issue
Block a user