#include #include #include /* maximum number of employees that can be stored at once (relevant only to storage using an array) */ #define MAX_EMPLOYEES 200 #define MAX_NAME_LENGTH 100 #define MAX_JOB_LENGTH 100 /* Employee structure */ struct Employee { /* Employee details */ char name[MAX_NAME_LENGTH+1]; /* name string */ char sex; /* sex identifier, either 'M' or 'F' */ int age; /* age */ char job[MAX_JOB_LENGTH+1]; /* job string */ /* pointers to previous and next employee structures in the linked list (for if you use a linked list instead of an array) */ struct Employee *prev, *next; }; typedef struct Employee emp; emp *list_root = NULL; /* read_line(): * * Read line of characters from file pointer "fp", copying the characters * into the "line" string, up to a maximum of "max_length" characters, plus * one for the string termination character '\0'. Reading stops upon * encountering the end-of-line character '\n', for which '\0' is substituted * in the string. If the end of file character EOF is reached before the end * of the line, the failure condition (-1) is returned. If the line is longer * than the maximum length "max_length" of the string, the extra characters * are read but ignored. Success is returned (0) on successfully reading * a line. */ static int read_line ( FILE *fp, char *line, int max_length ) { int i; char ch; /* initialize index to string character */ i = 0; /* read to end of line, filling in characters in string up to its maximum length, and ignoring the rest, if any */ for(;;) { /* read next character */ ch = fgetc(fp); /* check for end of file error */ if ( ch == EOF ) return -1; /* check for end of line */ if ( ch == '\n' ) { /* terminate string and return */ line[i] = '\0'; return 0; } /* fill character in string if it is not already full*/ if ( i < max_length ) line[i++] = ch; } /* the program should never reach here */ return -1; } /* read_string(): * * Reads a line from the input file pointer "fp", starting with the "prefix" * string, and filling the string "string" with the remainder of the contents * of the line. If the start of the line does not match the "prefix" string, * the error condition (-1) is returned. Having read the prefix string, * read_string() calls read_line() to read the remainder of the line into * "string", up to a maximum length "max_length", and returns the result. */ static int read_string ( FILE *fp, char *prefix, char *string, int max_length ) { int i; /* read prefix string */ for ( i = 0; i < strlen(prefix); i++ ) if ( fgetc(fp) != prefix[i] ) /* file input doesn't match prefix */ return -1; /* read remaining part of line of input into string */ return ( read_line ( fp, string, max_length ) ); } /* menu_add_employee(): * * Add new employee to database */ static void menu_add_employee(void) { /* fill in the code here in part 1, and add any extra functions you need */ emp *newemp; newemp = (emp *)malloc(sizeof(emp)); fprintf(stderr, "Enter Name: "); read_line(stdin, newemp->name, MAX_NAME_LENGTH + 1); char gender; /* Infinite loop to get correctly formatted gender */ for(;;){ fprintf(stderr, "Enter Gender: "); gender = getchar(); if(gender == '\n') gender = getchar(); if(gender == 'F' || gender == 'M') break; fprintf(stderr, "Enter either M or F\n"); } newemp->sex = gender; int age; for(;;){ /* Infinite loop with checks for age */ fprintf(stderr, "Enter Age: "); scanf("%i", &age); if(age > 0) break; fprintf(stderr, "Enter a Positive Integer\n"); } newemp->age = age; getchar(); fprintf(stderr, "Enter Job: "); read_line(stdin, newemp->job, MAX_JOB_LENGTH + 1); /* Following inserts employee into list, sorting at entry */ if(list_root == NULL){ /*No Employees*/ newemp->prev = NULL; newemp->next = list_root; list_root = newemp; }else{ if(strcmp(newemp->name, list_root->name) < 1){ /* Checks if needs to be new first employee */ newemp->prev = NULL; newemp->next = list_root; list_root = newemp; }else{ emp* marker = list_root; /* Marker moves through to end of list */ while(marker->next != NULL){ marker = marker->next; } if(strcmp(newemp->name, marker->name) > 0){ /* Checks if employee needs to be new last employee */ marker->next = newemp; newemp->prev = marker; newemp->next = NULL; }else{ marker = list_root; while(marker->next != NULL){ /* Checks rest of list inbetween */ if(strcmp(newemp->name, marker->name) > 0 && strcmp(newemp->name, marker->next->name) <= 0){ newemp->next = marker->next; newemp->prev = marker; marker->next->prev = newemp; marker->next = newemp; } marker = marker->next; } } } } } /* menu_print_database(): * * Print database of employees to standard output. */ static void menu_print_database(void) { /* fill in the code here in part 1, and add any extra functions you need */ if(list_root != NULL){ /* Only prints if list root is not empty */ emp* marker = list_root; do{ printf("Name: %s\n", marker->name); printf("Sex: %c\n", marker->sex); printf("Age: %i\n", marker->age); printf("Job: %s\n\n", marker->job); marker = marker->next; }while(marker->name != NULL); }else{ fprintf(stderr, "Nothing To Print"); } } /* menu_delete_employee(): * * Delete new employee from database. */ static void menu_delete_employee(void) { /* fill in the code here in part 2, and add any extra functions you need */ } /* read file containing database of employees */ static void read_employee_database ( char *file_name ) { /* fill in the code here in part 3, and add any extra functions you need */ } /* codes for menu */ #define ADD_CODE 0 #define DELETE_CODE 1 #define PRINT_CODE 2 #define EXIT_CODE 3 int main ( int argc, char *argv[] ) { /* check arguments */ if ( argc != 1 && argc != 2 ) { fprintf ( stderr, "Usage: %s []\n", argv[0] ); exit(-1); } /* read database file if provided, or start with empty database */ if ( argc == 2 ) read_employee_database ( argv[1] ); for(;;) { int choice, result; char line[301]; /* print menu to standard error */ fprintf ( stderr, "\nOptions:\n" ); fprintf ( stderr, "%d: Add new employee to database\n", ADD_CODE ); fprintf ( stderr, "%d: Delete employee from database\n", DELETE_CODE ); fprintf ( stderr, "%d: Print database to screen\n", PRINT_CODE ); fprintf ( stderr, "%d: Exit database program\n", EXIT_CODE ); fprintf ( stderr, "\nEnter option: " ); if ( read_line ( stdin, line, 300 ) != 0 ) continue; result = sscanf ( line, "%d", &choice ); if ( result != 1 ) { fprintf ( stderr, "corrupted menu choice\n" ); continue; } switch ( choice ) { case ADD_CODE: /* add employee to database */ menu_add_employee(); break; case DELETE_CODE: /* delete employee from database */ menu_delete_employee(); break; case PRINT_CODE: /* print database contents to screen (standard output) */ menu_print_database(); break; /* exit */ case EXIT_CODE: break; default: fprintf ( stderr, "illegal choice %d\n", choice ); break; } /* check for exit menu choice */ if ( choice == EXIT_CODE ) break; } return 0; }