Instructions
Requirements and Specifications
Solution
/* PLEASE DO NOT MODIFY A SINGLE STATEMENT IN THE TEXT BELOW.
READ THE FOLLOWING CAREFULLY AND FILL IN THE GAPS.
I hereby declare that all the work that was required to solve the following problem including designing the algorithms and writing the code below, is solely my own and that I received no help in creating this solution and I have not discussed my solution with anybody. I affirm that I have read and understood the Senate Policy on Academic honesty at https://secretariat-policies.info.yorku.ca/policies/academic-honesty-senate-policy-on/ and I am well aware of the seriousness of the matter and the penalties that I will face as a result of committing plagiarism in this assignment.
BY FILLING THE GAPS,YOU ARE SIGNING THE ABOVE STATEMENTS.
Full Name:
Student Number:
Course Section:
eecs user id:
*/
#include
#include
#include
#include
#define SIZE 30
#define fieldLength 200
#define diskFile "diskFile.dat"
#define courseFile "course.txt"
struct db_type
{
char name[fieldLength];
int age;
char course1[fieldLength];
char course2[fieldLength];
char status[fieldLength];
};
struct courseInfo
{
char code [20]; // e.g., EECS2030
char title [fieldLength];
char date [20];
char time_start [20];
char time_end [20];
char location [20];
};
struct courseInfo courseArr[SIZE]; // global variable array of struc
char prompt_menu(void);
void init_list(struct db_type * pArr[]);
void clearDB(struct db_type * pArr[]);
void init_courseArr(void);
void writeDisk(struct db_type * pArr[]);
void emptyDisk(void);
void loadDisk(struct db_type * pArr[]);
void displayCourses(void);
void enterNew(struct db_type * pArr[SIZE]);
void displayDB(struct db_type * pArr[]);
void removeRecord (struct db_type * pArr[]);
void swap(struct db_type * pArr[]);
void sort(struct db_type * pArr[]);
int main(int argc, char *argv[])
{
struct db_type * db_pArr[SIZE]; // main db storage
init_list(db_pArr); // set to NULL
init_courseArr(); // load course from diskfile
char choice;
for(; ;){
choice = prompt_menu();
switch (choice)
{
case 'n': enterNew(db_pArr); break;
case 'd': displayDB(db_pArr); break;
case 'w': writeDisk(db_pArr); break;
case 'l': loadDisk(db_pArr); break;
case 's': sort(db_pArr); break;
case 'c': clearDB(db_pArr); break;
case 'e': emptyDisk();break;
case 'v': displayCourses();break;
case 'p': swap(db_pArr); break;
case 'r': removeRecord(db_pArr);break;
case 'q': exit(1); // terminate the whole program
}
}
return 0;
}
int indexOfCourse(char *s) {
int i, found = -1;
char prefix[80] = "EECS";
char trimmed[80] = "";
strncat(prefix, s, strlen(s)-1);
strncat(trimmed, s, strlen(s)-1);
for (i = 0; ;i++) {
if (strcmp(courseArr[i].code, "EECS0000") == 0) {
break;
}
if (strcmp(courseArr[i].code, prefix) == 0 || strcmp(courseArr[i].code, trimmed) == 0) {
found = i;
break;
}
}
return found;
}
int indexOfRecord(struct db_type * pArr[], char *s) {
int i, found = -1;
for (i = 0; ;i++) {
if (pArr[i] == NULL) {
break;
}
if (strcmp(pArr[i]->name, s) == 0) {
found = i;
break;
}
}
return found;
}
int timeOverlap(int s1, int e1, int s2, int e2) {
if ((s1 - s2) * (s1 - e2) < 0) {
return 1;
}
if ((s2 - s1) * (s2 - e1) < 0) {
return 1;
}
if (s1 == s2 || e1 == e2) {
return 1;
}
return 0;
}
int checkOverlap(int c1, int c2) {
int i, j, sh1, sm1, eh1, em1, sh2, sm2, eh2, em2;
char *d1 = courseArr[c1].date;
char *d2 = courseArr[c2].date;
char c;
sscanf(courseArr[c1].time_start, "%d:%d", &sh1, &sm1);
sscanf(courseArr[c1].time_end, "%d:%d", &eh1, &em1);
sscanf(courseArr[c2].time_start, "%d:%d", &sh2, &sm2);
sscanf(courseArr[c2].time_end, "%d:%d", &eh2, &em2);
for(i = 0; i
for (j = 0; j
if (d1[i] == d2[j]) {
if (timeOverlap(sh1*100 + sm1, eh1*100 + em1, sh2*100 + sm2, eh2*100 + em2)) {
return 1;
}
}
}
}
return 0;
}
void init_list(struct db_type * pArr[]){
int t;
for (t=0; t
{
pArr[t]= NULL;
}
}
void clearDB(struct db_type * pArr[]){
char c3[3];
printf("are you sure to clear db? (y) or (n)? ");
fgets(c3,3,stdin);
if(! strcmp(c3, "y\n"))
init_list(pArr);
}
char prompt_menu(void){
char s[80];
while(1){
printf("\n-----------------------------------------------------------------\n");
printf("| %-20s","(N)ew record");
printf("%-20s","(R)emove record");
printf("Swa(p) records\t|\n");
printf("| %-20s","(S)ort database");
printf("%-20s","(C)lear database");
printf("(D)isplay db\t|\n");
printf("| %-20s","(L)oad disk");
printf("%-20s","(W)rite disk");
printf("(E)mpty disk\t|\n");
printf("| %-20s", "(V)iew courses");//|\tSwa(p) record\t(Q)uit\t\t\t\t|\n");
printf("%-20s","(Q)uit");
printf("*Case Insensitive*\t|\n");
printf("-----------------------------------------------------------------\n");
printf("choose one: ");
fgets(s,50, stdin); // \n added
if (strlen(s) == 2 && strchr("edlsuqrcwnvpr", tolower(*s)))
return tolower(*s); // s[0], return the first character of s
//else
printf("not a valid input!\n");
}
}
/* display all or specified course */
void displayCourses(void){
// the provide PE2.out uses "%s\t%-40s%-5s %s-%s %s\n" as formatting string for printing each course info
char s[80];
int i;
printf("choose code (or 'a')? ");
fgets(s,50, stdin); // \n added
if (strlen(s) == 2 && strchr("a", tolower(*s))) {
printf("=================================================================================\n");
for (i = 0; ;i++) {
if (strcmp(courseArr[i].code, "EECS0000") == 0) {
break;
}
printf("%s\t%-40s%-5s %s-%s %s\n", courseArr[i].code, courseArr[i].title, courseArr[i].date, courseArr[i].time_start, courseArr[i].time_end, courseArr[i].location);
}
printf("=================================================================================\n");
}
else {
int found = indexOfCourse(s);
if (found >= 0) {
printf("%s\t%-40s%-5s %s-%s %s\n", courseArr[found].code, courseArr[found].title, courseArr[found].date, courseArr[found].time_start, courseArr[found].time_end, courseArr[found].location);
}
else {
printf("error! course does not exist\n");
}
}
}
/* input items into the list */
void enterNew(struct db_type * pArr[SIZE]){
int i;
int size, c1, c2;
char tmp[80];
for (i = 0; ;i++) {
if (pArr[i] == NULL) {
break;
}
}
size = i;
pArr[size] = (struct db_type *) malloc (sizeof(struct db_type));
printf("name: ");
fgets(tmp,50, stdin);
strncpy(pArr[i]->name, tmp, strlen(tmp) - 1);
pArr[i]->name[strlen(tmp) - 1] = 0;
printf("age: ");
fgets(tmp,50, stdin);
pArr[size]->age = atoi(tmp);
printf("course1: ");
while(1) {
fgets(pArr[size]->course1,50, stdin);
c1 = indexOfCourse(pArr[size]->course1);
if (c1 >= 0) {
break;
}
printf("course does not exist, enter again: ");
}
printf("course2: ");
while(1) {
fgets(pArr[size]->course2,50, stdin);
c2 = indexOfCourse(pArr[size]->course2);
if (c2 >= 0) {
break;
}
printf("course does not exist, enter again: ");
}
if (checkOverlap(c1, c2) == 1) {
strcpy(pArr[size]->status,"ATTENTION! time conflict");
printf("ATTENTION! time conflict\n");
}
else {
strcpy(pArr[size]->status,"SUCCESSFUL! no time conflict");
printf("SUCCESSFUL! no time conflict\n");
}
}
/* display records */
void displayDB(struct db_type * pArr[]){
int i, j;
int counter = 0;
printf("===============================\n");
for(i = 0; i
int c1, c2;
if (pArr[i] == NULL) {
break;
}
printf("\n");
printf("%-10s%s\n", "name:", pArr[i]->name);
printf("%-10s%d\n", "age:", pArr[i]->age);
printf("%-10s", "course1:");
c1 = indexOfCourse(pArr[i]->course1);
printf("%s\t%-40s%-5s %s-%s %s\n", courseArr[c1].code, courseArr[c1].title, courseArr[c1].date, courseArr[c1].time_start, courseArr[c1].time_end, courseArr[c1].location);
printf("%-10s", "course1:");
c2 = indexOfCourse(pArr[i]->course2);
printf("%s\t%-40s%-5s %s-%s %s\n", courseArr[c2].code, courseArr[c2].title, courseArr[c2].date, courseArr[c2].time_start, courseArr[c2].time_end, courseArr[c2].location);
printf("%-10s%s\n", "remarks:", pArr[i]->status);
printf("\n");
counter++;
}
printf("==========%2d records ==========\n", counter);
}
/* remove an existing item */
void removeRecord (struct db_type * pArr[])
{
char tmp[80];
char trimmed[80];
int index, i;
printf("enter full name to remove: ");
fgets(tmp, 50, stdin);
strncpy(trimmed, tmp, strlen(tmp) - 1);
trimmed[strlen(tmp)-1] = 0;
index = indexOfRecord(pArr, trimmed);
if (index < 0) {
printf("record not found\n");
}
else {
for (i = index; ;i++) {
if (pArr[i+1] == NULL) {
pArr[i] = NULL;
break;
}
pArr[i] = pArr[i+1];
}
printf("record [%s] removed successfully.", trimmed);
}
}
/* swap records */
void swap(struct db_type * pArr[]){
int i;
for (i = 0; ;i+=2) {
struct db_type *sw;
if (pArr[i] == NULL) {
return;
}
if (pArr[i+1] == NULL) {
return;
}
sw = pArr[i];
pArr[i] = pArr[i+1];
pArr[i+1] = sw;
}
}
/* load from course.txt, store into (global) array of courses */
void init_courseArr(void){
FILE *fr; //file pointer
fr = fopen (courseFile, "r");
char arr[50];
int count = 0;
while ((fgets(arr,100,fr)) != NULL)
{
strncpy(courseArr[count].code, arr, strlen(arr)-1); // remove \n
courseArr[count].code[strlen(arr)-1] = '\0'; //to be safe
fgets(arr,100,fr);
strncpy(courseArr[count].title , arr, strlen(arr)-1);
courseArr[count].title[strlen(arr)-1] = '\0'; //to be safe
fgets(arr,100,fr);
strncpy(courseArr[count].date, arr, strlen(arr)-1);
courseArr[count].date[strlen(arr)-1] = '\0'; //to be safe
// other ways, remove \n before
fgets(arr,100,fr);
arr[strlen(arr)-1] = '\0';
strcpy(courseArr[count].time_start, arr);
fgets(arr,100,fr);
arr[strlen(arr)-1] = '\0';
strcpy(courseArr[count].time_end, arr);
fgets(arr,100,fr);
arr[strlen(arr)-1] = '\0';
strcpy(courseArr[count].location, arr);
count++;
fgets(arr,100,fr); // read the empty line
}
strcpy(courseArr[count].code, "EECS0000"); // a terminator token structure
fclose(fr);
}
/************************ DISK IO *****************************************************************/
void writeDisk(struct db_type * pArr[]){
FILE *fp;
int i;
if ( (fp=fopen(diskFile,"ab")) == NULL)
{
printf("cannot open file\n");
return;
}
for (i=0; i< SIZE ; i++)
{
if ( pArr[i] != NULL)
{
if (fwrite( pArr[i], sizeof(struct db_type), 1, fp) != 1)
{
printf("file write error\n");
}
}
}
fclose(fp);
}
void emptyDisk(void) {
FILE *fp;
char c3[3];
printf("are you sure to empty disk? (y) or (n)? ");
fgets(c3,3,stdin);
if(strcmp(c3, "y\n"))
return;
//else
if ( (fp = fopen(diskFile,"w")) == NULL)
{
printf("no file to open\n");
return;
}
fclose(fp); // open close, will empty the file
}
void loadDisk(struct db_type * pArr[]){
FILE *fp;
int i;
char c3[3];
printf("will overwrite current records. are you sure to load disk? (y) or (n)? ");
fgets(c3,3,stdin);
if(strcmp(c3, "y\n"))
return;
struct db_type * tmp;
if ( (fp = fopen(diskFile,"r")) == NULL)
{
printf("cannot open file\n");
return;
}
init_list(pArr);
for (i=0; i < SIZE ; i++)
{
tmp = (struct db_type *) malloc (sizeof(struct db_type));
if (fread( tmp, sizeof(struct db_type), 1, fp) != 1)
{
if (feof(fp))
{ fclose(fp);
return;
}
printf("file read error\n");
}
else pArr[i] = tmp;
}
}
/****bonus*************************************************************************************/
/* sort the records by ages */
void sort(struct db_type * pArr[])
{
int i, j;
for (i = 0; ;i++) {
if (pArr[i] == NULL) {
break;
}
for (j = i+1; ;j++) {
if (pArr[j] == NULL) {
break;
}
if (pArr[i]->age > pArr[j]->age) {
struct db_type *sw = pArr[i];
pArr[i] = pArr[j];
pArr[j] = sw;
}
}
}
}