initial commit
This commit is contained in:
commit
c5f514229b
106
assessment1date/date1.c
Normal file
106
assessment1date/date1.c
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
struct _date {
|
||||||
|
int day;
|
||||||
|
int month;
|
||||||
|
int year;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _date date;
|
||||||
|
|
||||||
|
date getDate();
|
||||||
|
int dateDiff(date date1, date date2);
|
||||||
|
|
||||||
|
main(){
|
||||||
|
|
||||||
|
date date1 = getDate();
|
||||||
|
date date2 = getDate();
|
||||||
|
|
||||||
|
int diff = dateDiff(date1, date2);
|
||||||
|
|
||||||
|
printf("%i\n", diff);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
getDate function to get user entry of a valid date and
|
||||||
|
returns a date variable type
|
||||||
|
*/
|
||||||
|
date getDate(){
|
||||||
|
date entrydate = {0,0,0};
|
||||||
|
int days[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
|
||||||
|
char mark[2];
|
||||||
|
|
||||||
|
/*
|
||||||
|
loop to get entry of date that quits when a valid date is given
|
||||||
|
should only run once if a valid date is entered, any errors result in continue statement
|
||||||
|
*/
|
||||||
|
while(1){
|
||||||
|
|
||||||
|
char input[12];
|
||||||
|
|
||||||
|
scanf("%s", input);
|
||||||
|
|
||||||
|
sscanf(input,"%i%c%i%c%i", &entrydate.day, &mark[0], &entrydate.month, &mark[1], &entrydate.year);
|
||||||
|
//printf("%i\t%i\t%i\n", entrydate.day, entrydate.month, entrydate.year);
|
||||||
|
|
||||||
|
if(mark[0] != mark[1])
|
||||||
|
{
|
||||||
|
fprintf(stderr, "ERROR: Use Consistent Delimeters\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mark[0] != '/' && mark[0] != '-')
|
||||||
|
{
|
||||||
|
fprintf(stderr, "ERROR: Use either / or - as delimiters\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(entrydate.year > 10000 | entrydate.year < 1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "ERROR: Enter A Valid Year, Less than 10000 and Greater Than 0\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(entrydate.month > 12 | entrydate.year < 1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "ERROR: Enter A Valid Month\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//checks that day entered is not outside range for month
|
||||||
|
if(entrydate.day > days[(entrydate.month) - 1] | entrydate.day < 1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "ERROR: Enter A Valid Day For The Month Entered\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return entrydate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function to find difference between two dates
|
||||||
|
|
||||||
|
Calculated based on turning dates into number of days since 0/0/0000
|
||||||
|
and finding difference between these two numbers
|
||||||
|
*/
|
||||||
|
int dateDiff(date date1, date date2){
|
||||||
|
|
||||||
|
int date1day = 0, date2day = 0;
|
||||||
|
int days[] = {0,31,59,90,120,151,181,212,243,273,304,334}; //Cumulative Day Array
|
||||||
|
|
||||||
|
date1day += date1.day;
|
||||||
|
date1day += days[(date1.month) - 1];
|
||||||
|
date1day += (365*(date1.year));
|
||||||
|
|
||||||
|
date2day += date2.day;
|
||||||
|
date2day += days[(date2.month) - 1];
|
||||||
|
date2day += (365*(date2.year));
|
||||||
|
|
||||||
|
return (date2day - date1day);
|
||||||
|
}
|
139
assessment1date/date2.c
Normal file
139
assessment1date/date2.c
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
struct _date {
|
||||||
|
int day;
|
||||||
|
int month;
|
||||||
|
int year;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _date date;
|
||||||
|
|
||||||
|
date getDate();
|
||||||
|
int dateDiff(date date1, date date2);
|
||||||
|
|
||||||
|
main(){
|
||||||
|
|
||||||
|
date date1 = getDate();
|
||||||
|
date date2 = getDate();
|
||||||
|
|
||||||
|
int diff = dateDiff(date1, date2);
|
||||||
|
|
||||||
|
printf("%i\n", diff);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
getDate function to get user entry of a valid date and
|
||||||
|
returns a date variable type
|
||||||
|
*/
|
||||||
|
date getDate(){
|
||||||
|
date entrydate = {0,0,0};
|
||||||
|
int days[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
|
||||||
|
int leapdays[12] = {31,29,31,30,31,30,31,31,30,31,30,31};
|
||||||
|
char mark[2];
|
||||||
|
|
||||||
|
/*
|
||||||
|
loop to get entry of date that quits when a valid date is given
|
||||||
|
should only run once if a valid date is entered, any errors result in continue statement
|
||||||
|
*/
|
||||||
|
while(1){
|
||||||
|
|
||||||
|
char input[12];
|
||||||
|
|
||||||
|
scanf("%s", input);
|
||||||
|
|
||||||
|
sscanf(input,"%i%c%i%c%i", &entrydate.day, &mark[0], &entrydate.month, &mark[1], &entrydate.year);
|
||||||
|
//printf("%i\t%i\t%i\n", entrydate.day, entrydate.month, entrydate.year);
|
||||||
|
|
||||||
|
if(mark[0] != mark[1])
|
||||||
|
{
|
||||||
|
fprintf(stderr, "ERROR: Use Consistent Delimeters\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mark[0] != '/' && mark[0] != '-')
|
||||||
|
{
|
||||||
|
fprintf(stderr, "ERROR: Use either / or - as delimiters\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(entrydate.year > 10000 | entrydate.year < 1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "ERROR: Enter A Valid Year, Less than 10000 and Greater Than 0\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(entrydate.month > 12 | entrydate.year < 1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "ERROR: Enter A Valid Month\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//checks that day entered is not outside range for month
|
||||||
|
|
||||||
|
if(entrydate.year % 4 == 0){
|
||||||
|
|
||||||
|
if(entrydate.day > leapdays[(entrydate.month) - 1] | entrydate.day < 1){
|
||||||
|
|
||||||
|
fprintf(stderr, "ERROR: Enter A Valid Day For The Month Entered\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
|
||||||
|
if(entrydate.day > days[(entrydate.month) - 1] | entrydate.day < 1){
|
||||||
|
|
||||||
|
fprintf(stderr, "ERROR: Enter A Valid Day For The Month Entered\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return entrydate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function to find difference between two dates
|
||||||
|
|
||||||
|
Calculated based on turning dates into number of days since 0/0/0000
|
||||||
|
and finding difference between these two numbers
|
||||||
|
*/
|
||||||
|
int dateDiff(date date1, date date2){
|
||||||
|
|
||||||
|
int date1day = 0, date2day = 0;
|
||||||
|
int days[] = {0,31,59,90,120,151,181,212,243,273,304,334}; //Cumulative Day Array
|
||||||
|
|
||||||
|
//DATE 1 CONVERSION
|
||||||
|
date1day += date1.day;
|
||||||
|
date1day += days[(date1.month) - 1];
|
||||||
|
date1day += (365*(date1.year));
|
||||||
|
|
||||||
|
if(date1.year % 4 == 0){ //Leap Year Handling
|
||||||
|
date1day += ((date1.year / 4) - 1);
|
||||||
|
if(date1.month > 2){
|
||||||
|
date1day++;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
date1day += (date1.year / 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
//DATE 2 CONVERSION
|
||||||
|
date2day += date2.day;
|
||||||
|
date2day += days[(date2.month) - 1];
|
||||||
|
date2day += (365*(date2.year));
|
||||||
|
|
||||||
|
if(date2.year % 4 == 0){ //Leap Year Handling
|
||||||
|
date2day += ((date2.year / 4) - 1);
|
||||||
|
if(date2.month > 2){
|
||||||
|
date2day++;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
date2day += (date2.year / 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (date2day - date1day);
|
||||||
|
}
|
208
assessment1date/date3.c
Normal file
208
assessment1date/date3.c
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Program works by letting a user input an amount of dates and converting each into an integer value
|
||||||
|
representing the number of days since 0/0/0000 in the same way as date2.c
|
||||||
|
|
||||||
|
From here those integer values are copied onto another array and sorted into ascending order
|
||||||
|
|
||||||
|
In theory to print the dates because the unsorted array matches up to the date array in position,
|
||||||
|
going through the sorted array one value at a time and for each one finding the same value in the
|
||||||
|
unsorted array will give the position of the date to be printed
|
||||||
|
|
||||||
|
In practice this was done with a while loop nested in a for loop.
|
||||||
|
|
||||||
|
The outside for loop goes through the array of sorted integers
|
||||||
|
The inside while loop checks if the i element of the sorted integers is equal to the first element of the non sorted array
|
||||||
|
|
||||||
|
If it is it will skip the loop and print the first date
|
||||||
|
|
||||||
|
If not it will increment elementnum and check it against this integers element of the unsorted array
|
||||||
|
This will continue through the unsorted array until the matching integer value is found
|
||||||
|
|
||||||
|
At this point the elementnum is the element number of the date to be printed
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
struct _date {
|
||||||
|
int day;
|
||||||
|
int month;
|
||||||
|
int year;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _date date;
|
||||||
|
|
||||||
|
date getDate();
|
||||||
|
int dayConvert(date date1);
|
||||||
|
void printDate(date date1);
|
||||||
|
|
||||||
|
main(){
|
||||||
|
|
||||||
|
date *datearray; //array for inputted dates
|
||||||
|
int *intarray; //array for inputted dates after conversion to days
|
||||||
|
int *sorted_intarray; //sorted array of converted days
|
||||||
|
|
||||||
|
int num_dates;
|
||||||
|
scanf("%i", &num_dates);
|
||||||
|
|
||||||
|
datearray = (date *)malloc(sizeof(date) * num_dates);
|
||||||
|
intarray = (int *)malloc(sizeof(int) * num_dates);
|
||||||
|
sorted_intarray = (int *)malloc(sizeof(int) * num_dates);
|
||||||
|
|
||||||
|
|
||||||
|
int i, j, temp;
|
||||||
|
for(i = 0; i < num_dates; i++) //GET DATES
|
||||||
|
{
|
||||||
|
datearray[i] = getDate();
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; i < num_dates; i++) //CONVERT DATES TO INTEGERS
|
||||||
|
{
|
||||||
|
intarray[i] = dayConvert(datearray[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; i < num_dates; i++) //MAKE COPY OF INTEGERS
|
||||||
|
{
|
||||||
|
sorted_intarray[i] = intarray[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; i < num_dates; i++){ //SORT INTEGERS
|
||||||
|
|
||||||
|
for(j = i + 1; j < num_dates; j++){
|
||||||
|
|
||||||
|
if(sorted_intarray[i] > sorted_intarray[j]){
|
||||||
|
|
||||||
|
temp = sorted_intarray[i];
|
||||||
|
sorted_intarray[i] = sorted_intarray[j];
|
||||||
|
sorted_intarray[j] = temp;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; i < num_dates; i++){ //FIND MATCHING INTEGER AND PRINT DATE
|
||||||
|
|
||||||
|
int elementnum = 0;
|
||||||
|
|
||||||
|
while(sorted_intarray[i] != intarray[elementnum])
|
||||||
|
{
|
||||||
|
elementnum++;
|
||||||
|
}
|
||||||
|
|
||||||
|
printDate(datearray[elementnum]);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(datearray);
|
||||||
|
free(intarray);
|
||||||
|
free(sorted_intarray);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
getDate function to get user entry of a valid date and
|
||||||
|
returns a date variable type
|
||||||
|
*/
|
||||||
|
date getDate(){
|
||||||
|
date entrydate = {0,0,0};
|
||||||
|
int days[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
|
||||||
|
int leapdays[12] = {31,29,31,30,31,30,31,31,30,31,30,31};
|
||||||
|
char mark[2];
|
||||||
|
|
||||||
|
/*
|
||||||
|
loop to get entry of date that quits when a valid date is given
|
||||||
|
should only run once if a valid date is entered, any errors result in continue statement
|
||||||
|
*/
|
||||||
|
while(1){
|
||||||
|
|
||||||
|
char input[12];
|
||||||
|
|
||||||
|
scanf("%s", input);
|
||||||
|
|
||||||
|
sscanf(input,"%i%c%i%c%i", &entrydate.day, &mark[0], &entrydate.month, &mark[1], &entrydate.year);
|
||||||
|
//printf("%i\t%i\t%i\n", entrydate.day, entrydate.month, entrydate.year);
|
||||||
|
|
||||||
|
if(mark[0] != mark[1])
|
||||||
|
{
|
||||||
|
fprintf(stderr, "ERROR: Use Consistent Delimeters\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mark[0] != '/' && mark[0] != '-')
|
||||||
|
{
|
||||||
|
fprintf(stderr, "ERROR: Use either / or - as delimiters\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(entrydate.year > 10000 | entrydate.year < 1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "ERROR: Enter A Valid Year, Less than 10000 and Greater Than 0\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(entrydate.month > 12 | entrydate.year < 1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "ERROR: Enter A Valid Month\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//checks that day entered is not outside range for month
|
||||||
|
|
||||||
|
if(entrydate.year % 4 == 0){
|
||||||
|
|
||||||
|
if(entrydate.day > leapdays[(entrydate.month) - 1] | entrydate.day < 1){
|
||||||
|
|
||||||
|
fprintf(stderr, "ERROR: Enter A Valid Day For The Month Entered\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
|
||||||
|
if(entrydate.day > days[(entrydate.month) - 1] | entrydate.day < 1){
|
||||||
|
|
||||||
|
fprintf(stderr, "ERROR: Enter A Valid Day For The Month Entered\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return entrydate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function to convert date into number of days since 0/0/0000 used for sorting
|
||||||
|
*/
|
||||||
|
int dayConvert(date date1){
|
||||||
|
|
||||||
|
int date1day = 0;
|
||||||
|
int days[] = {0,31,59,90,120,151,181,212,243,273,304,334};
|
||||||
|
|
||||||
|
date1day += date1.day;
|
||||||
|
date1day += days[(date1.month) - 1];
|
||||||
|
date1day += (365*(date1.year));
|
||||||
|
|
||||||
|
//Leap Year Handling
|
||||||
|
if(date1.year % 4 == 0){
|
||||||
|
date1day += ((date1.year / 4) - 1);
|
||||||
|
if(date1.month > 2){
|
||||||
|
date1day++;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
date1day += (date1.year / 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
return date1day;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function to print dates
|
||||||
|
*/
|
||||||
|
void printDate(date date1){
|
||||||
|
|
||||||
|
printf("%i/%i/%i\n", date1.day, date1.month, date1.year);
|
||||||
|
|
||||||
|
}
|
295
assessment2employee/employee1.c
Normal file
295
assessment2employee/employee1.c
Normal file
@ -0,0 +1,295 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/* 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 [<database-file>]\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;
|
||||||
|
}
|
336
assessment2employee/employee2.c
Normal file
336
assessment2employee/employee2.c
Normal file
@ -0,0 +1,336 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
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(;;){
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
if(list_root == NULL){
|
||||||
|
newemp->prev = NULL;
|
||||||
|
newemp->next = list_root;
|
||||||
|
list_root = newemp;
|
||||||
|
}else{
|
||||||
|
|
||||||
|
if(strcmp(newemp->name, list_root->name) < 1){
|
||||||
|
newemp->prev = NULL;
|
||||||
|
newemp->next = list_root;
|
||||||
|
list_root = newemp;
|
||||||
|
}else{
|
||||||
|
|
||||||
|
emp* marker = list_root;
|
||||||
|
while(marker->next != NULL){
|
||||||
|
marker = marker->next;
|
||||||
|
}
|
||||||
|
if(strcmp(newemp->name, marker->name) > 0){
|
||||||
|
marker->next = newemp;
|
||||||
|
newemp->prev = marker;
|
||||||
|
newemp->next = NULL;
|
||||||
|
}else{
|
||||||
|
marker = list_root;
|
||||||
|
while(marker->next != NULL){
|
||||||
|
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){
|
||||||
|
|
||||||
|
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 */
|
||||||
|
|
||||||
|
fprintf(stderr, "Enter Name To Be Deleted: ");
|
||||||
|
char name[MAX_NAME_LENGTH + 1];
|
||||||
|
//read_line(stdin, name, MAX_NAME_LENGTH + 1);
|
||||||
|
fgets(name, MAX_NAME_LENGTH + 1, stdin);
|
||||||
|
|
||||||
|
int found = 0; /* boolean check to mark if employee was found */
|
||||||
|
|
||||||
|
emp* marker = list_root;
|
||||||
|
for(;;){
|
||||||
|
if(strcmp(marker->name, name) == 0){
|
||||||
|
|
||||||
|
if(marker == list_root){ /* First Employee */
|
||||||
|
if(marker->next == NULL){ /* Only Employee */
|
||||||
|
free(marker);
|
||||||
|
list_root = NULL;
|
||||||
|
}else{ /* First Employee */
|
||||||
|
list_root = marker->next;
|
||||||
|
marker->next->prev = NULL;
|
||||||
|
free(marker);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if(marker->next == NULL){ /* Last Employee */
|
||||||
|
marker->prev->next = NULL;
|
||||||
|
free(marker);
|
||||||
|
}else{ /* Somewhere in Middle Of List */
|
||||||
|
marker->prev->next = marker->next;
|
||||||
|
marker->next->prev = marker->prev;
|
||||||
|
free(marker);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
found = 1;
|
||||||
|
break;
|
||||||
|
}else{
|
||||||
|
if(marker->next != NULL){ /* Progresses List */
|
||||||
|
marker = marker->next;
|
||||||
|
}else{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(found = 0) fprintf(stderr, "Name not Found\n");
|
||||||
|
|
||||||
|
getchar();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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 [<database-file>]\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;
|
||||||
|
}
|
391
assessment2employee/employee3.c
Normal file
391
assessment2employee/employee3.c
Normal file
@ -0,0 +1,391 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/* 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 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Moved sorting into separate function so it could be called by either add employee
|
||||||
|
or read database function */
|
||||||
|
|
||||||
|
static void insert_employee(emp* newemp){
|
||||||
|
|
||||||
|
if(list_root == NULL){
|
||||||
|
newemp->prev = NULL;
|
||||||
|
newemp->next = list_root;
|
||||||
|
list_root = newemp;
|
||||||
|
}else{
|
||||||
|
|
||||||
|
if(strcmp(newemp->name, list_root->name) < 1){
|
||||||
|
newemp->prev = NULL;
|
||||||
|
newemp->next = list_root;
|
||||||
|
list_root = newemp;
|
||||||
|
}else{
|
||||||
|
|
||||||
|
emp* marker = list_root;
|
||||||
|
while(marker->next != NULL){
|
||||||
|
marker = marker->next;
|
||||||
|
}
|
||||||
|
if(strcmp(newemp->name, marker->name) > 0){
|
||||||
|
marker->next = newemp;
|
||||||
|
newemp->prev = marker;
|
||||||
|
newemp->next = NULL;
|
||||||
|
}else{
|
||||||
|
marker = list_root;
|
||||||
|
while(marker->next != NULL){
|
||||||
|
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_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;
|
||||||
|
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(;;){
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
insert_employee(newemp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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){
|
||||||
|
|
||||||
|
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 */
|
||||||
|
|
||||||
|
fprintf(stderr, "Enter Name To Be Deleted: ");
|
||||||
|
char name[MAX_NAME_LENGTH + 1];
|
||||||
|
read_line(stdin, name, MAX_NAME_LENGTH + 1);
|
||||||
|
|
||||||
|
int found = 0;
|
||||||
|
|
||||||
|
emp* marker = list_root;
|
||||||
|
for(;;){
|
||||||
|
if(strcmp(marker->name, name) == 0){
|
||||||
|
|
||||||
|
if(list_root == marker){ //FIRST EMPLOYEE
|
||||||
|
if(marker->next == NULL){
|
||||||
|
free(marker);
|
||||||
|
list_root = NULL;
|
||||||
|
}else{
|
||||||
|
list_root = marker->next;
|
||||||
|
marker->next->prev = NULL;
|
||||||
|
free(marker);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if(marker->next == NULL){//LAST EMPLOYEE
|
||||||
|
marker->prev->next = NULL;
|
||||||
|
free(marker);
|
||||||
|
}else{
|
||||||
|
marker->prev->next = marker->next;
|
||||||
|
marker->next->prev = marker->prev;
|
||||||
|
free(marker);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
found = 1;
|
||||||
|
break;
|
||||||
|
}else{
|
||||||
|
if(marker->next != NULL){
|
||||||
|
marker = marker->next;
|
||||||
|
}else{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(found = 0) fprintf(stderr, "Name not Found\n");
|
||||||
|
|
||||||
|
getchar();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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 */
|
||||||
|
|
||||||
|
FILE *empfile;
|
||||||
|
empfile = fopen(file_name, "r");
|
||||||
|
|
||||||
|
if(empfile == NULL){ /* Checks file has opened correctly */
|
||||||
|
fprintf(stderr, "Error Opening %s File to Read", file_name);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(;;){ /*Infinite loop that reads in employees until can't read any more*/
|
||||||
|
emp* newemp;
|
||||||
|
newemp = (emp *)malloc(sizeof(emp));
|
||||||
|
|
||||||
|
int name_check = read_string(empfile, "Name: ", newemp->name, MAX_NAME_LENGTH+1);
|
||||||
|
if(name_check == -1) break; /* This line exits loop when no new name can be found */
|
||||||
|
|
||||||
|
char gender[2]; /* sends string to be read to */
|
||||||
|
read_string(empfile, "Sex: ", gender, 2);
|
||||||
|
if(gender[0] != 'M' && gender[0] != 'F'){ /* Gender Check */
|
||||||
|
fprintf(stderr, "Incorrect Gender Format Found For Employee %s\n", newemp->name);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
newemp->sex = gender[0]; /* Takes first character of array for gender char */
|
||||||
|
|
||||||
|
|
||||||
|
int age;
|
||||||
|
char char_age[10];
|
||||||
|
read_string(empfile, "Age: ", char_age, 10);
|
||||||
|
age = atoi(char_age); /* Uses function to cast string as int, read_string only reads to strings */
|
||||||
|
if(age < 1){
|
||||||
|
fprintf(stderr, "Negative Age Found For Employee %s\n", newemp->name);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
newemp->age = age;
|
||||||
|
|
||||||
|
read_string(empfile, "Job: ", newemp->job, MAX_JOB_LENGTH+1);
|
||||||
|
|
||||||
|
insert_employee(newemp); /* Correctly sorts and inserts employee */
|
||||||
|
|
||||||
|
char carriage[2];
|
||||||
|
read_line(empfile, carriage, 1); /* Important line to skip blank line inbetween employees */
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(empfile); /* Close File */
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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 [<database-file>]\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;
|
||||||
|
}
|
248
assessment3gameOfLife/life1.c
Normal file
248
assessment3gameOfLife/life1.c
Normal file
@ -0,0 +1,248 @@
|
|||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function to check 3 x 3 grid around cell defined by co-ordinates given by
|
||||||
|
the arguments "row" and "column" for live neighbours
|
||||||
|
*/
|
||||||
|
int checkNeighbours(char **board, int row, int column){
|
||||||
|
|
||||||
|
int neighbours = 0;
|
||||||
|
|
||||||
|
int start_x = column - 1; /* Moves start co-ordinate to top left of 3 x 3 grid */
|
||||||
|
int start_y = row - 1;
|
||||||
|
int x,y;
|
||||||
|
for(y = 0; y < 3; y++){ /* Nested Loops to cycle through 3 x 3 grid */
|
||||||
|
for(x = 0; x < 3; x++){
|
||||||
|
if(board[start_y + y][start_x + x] == 'X'){
|
||||||
|
neighbours++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(board[row][column] == 'X') neighbours--;
|
||||||
|
|
||||||
|
/* Remove one neighbour if given cell is alive to avoid it being counted as a neighbour */
|
||||||
|
|
||||||
|
return neighbours;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function to return an empty board array with dimensions given in arguments r and c
|
||||||
|
*/
|
||||||
|
char** getBoard(int r, int c){
|
||||||
|
|
||||||
|
r+=2;
|
||||||
|
c+=2;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Adding 2 to r and c is done to add a border of empty cells around the board
|
||||||
|
|
||||||
|
This avoids trying to access unallocated memory
|
||||||
|
*/
|
||||||
|
|
||||||
|
int i, j;
|
||||||
|
char **board;
|
||||||
|
|
||||||
|
board = (char **)malloc(r * sizeof(char *));
|
||||||
|
for(i = 0; i < r; i++){
|
||||||
|
board[i] = (char *)malloc(c * sizeof(char)); /* Fill array with arrays */
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; i < r; i++)
|
||||||
|
for(j = 0; j < c; j++)
|
||||||
|
board[i][j] = ' '; /* Fills board with dead cells */
|
||||||
|
|
||||||
|
return board;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function that takes board input and applies rules to it,
|
||||||
|
returning a new board and deleting the old one
|
||||||
|
*/
|
||||||
|
char** getNextBoard(char **oldboard, int r, int c){
|
||||||
|
|
||||||
|
char** board = getBoard(r, c);
|
||||||
|
|
||||||
|
r+=2;
|
||||||
|
c+=2;
|
||||||
|
|
||||||
|
int x, y, neighbour;
|
||||||
|
for(y = 1; y < r - 1; y++){ /* Nested Loops to run through whole board */
|
||||||
|
for(x = 1; x < c - 1; x++){
|
||||||
|
neighbour = checkNeighbours(oldboard, y, x);
|
||||||
|
|
||||||
|
if(oldboard[y][x] == 'X'){
|
||||||
|
|
||||||
|
if(neighbour < 2) /* Rule 1 */
|
||||||
|
{
|
||||||
|
board[y][x] = 'o';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(neighbour == 2 || neighbour == 3) /* Rule 2 */
|
||||||
|
{
|
||||||
|
board[y][x] = 'X';
|
||||||
|
}
|
||||||
|
|
||||||
|
if(neighbour > 3) /* Rule 3 */
|
||||||
|
{
|
||||||
|
board[y][x] = 'o';
|
||||||
|
}
|
||||||
|
|
||||||
|
}else{
|
||||||
|
|
||||||
|
if(neighbour == 3) /* Rule 4 */
|
||||||
|
{
|
||||||
|
board[y][x] = 'X';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(oldboard);
|
||||||
|
return board;
|
||||||
|
}
|
||||||
|
|
||||||
|
void printBoard(char **board, int row, int column){
|
||||||
|
|
||||||
|
int x;
|
||||||
|
|
||||||
|
printf("*"); /* Top Line */
|
||||||
|
for(x = 0; x < column; x++){
|
||||||
|
printf("-");
|
||||||
|
}
|
||||||
|
printf("*\n");
|
||||||
|
|
||||||
|
|
||||||
|
int y;
|
||||||
|
for(y = 1; y < row + 1; y++){ /* Board */
|
||||||
|
|
||||||
|
printf("|");
|
||||||
|
|
||||||
|
for(x = 1; x < column + 1; x++){
|
||||||
|
|
||||||
|
/* Loop starts at 1 to take into account border around board */
|
||||||
|
|
||||||
|
if(board[y][x] == 'X'){
|
||||||
|
|
||||||
|
printf("X");
|
||||||
|
|
||||||
|
}else printf(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("|\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("*"); /* Bottom Line */
|
||||||
|
for(x = 0; x < column; x++){
|
||||||
|
printf("-");
|
||||||
|
}
|
||||||
|
printf("*\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
TESTING FUNCTION FOR DEBUGGING NOT USED IN PROGRAM
|
||||||
|
|
||||||
|
prints out board with x's and spaces replaced by integers
|
||||||
|
denoting number of neighbours each cell has
|
||||||
|
*/
|
||||||
|
void printNeighbourBoard(char **board, int row, int column){
|
||||||
|
|
||||||
|
int x;
|
||||||
|
|
||||||
|
printf("*");
|
||||||
|
for(x = 0; x < column; x++){
|
||||||
|
printf("-");
|
||||||
|
}
|
||||||
|
printf("*\n");
|
||||||
|
|
||||||
|
int y;
|
||||||
|
for(y = 1; y < row + 1; y++){
|
||||||
|
printf("|");
|
||||||
|
for(x = 1; x < column + 1; x++){
|
||||||
|
printf("%i", checkNeighbours(board, y, x));
|
||||||
|
}
|
||||||
|
printf("|\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("*");
|
||||||
|
for(x = 0; x < column; x++){
|
||||||
|
printf("-");
|
||||||
|
}
|
||||||
|
printf("*\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function called at runtime to open file and fill with cells
|
||||||
|
*/
|
||||||
|
char** populateBoard(char** board, char* filename, int row, int column){
|
||||||
|
|
||||||
|
FILE* file = fopen(filename, "r");
|
||||||
|
|
||||||
|
if(file == NULL){
|
||||||
|
fprintf(stderr, "ERROR: File %s Failed To Open\n", filename);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
int cells; /* Top line gives number of cells */
|
||||||
|
fscanf(file, "%i", &cells);
|
||||||
|
|
||||||
|
int i, r, c;
|
||||||
|
for(i = 0; i < cells; i++){
|
||||||
|
fscanf(file, "%i %i", &r, &c);
|
||||||
|
|
||||||
|
if(r > row || c > column){
|
||||||
|
fprintf(stderr, "ERROR: Co-ordinate found outside Board\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
board[r + 1][c + 1] = 'X';
|
||||||
|
/* +1 in each case takes into account border around board */
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(file);
|
||||||
|
|
||||||
|
return board;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(int argc, char * argv[]) {
|
||||||
|
|
||||||
|
int rounds = atoi(argv[4]);
|
||||||
|
int column = atoi(argv[2]);
|
||||||
|
int row = atoi(argv[3]);
|
||||||
|
|
||||||
|
if(rounds < 1){
|
||||||
|
fprintf(stderr, "ERROR: Positive Rounds Required\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
if(column < 1){
|
||||||
|
fprintf(stderr, "ERROR: Positive Width Required\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
if(row < 1){
|
||||||
|
fprintf(stderr, "ERROR: Positive Height Required\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
char ** board = getBoard(row, column); /* Create First Board */
|
||||||
|
|
||||||
|
board = populateBoard(board, argv[1], row, column); /* Fill Board */
|
||||||
|
|
||||||
|
printBoard(board, row, column); /* Print Board */
|
||||||
|
|
||||||
|
int x;
|
||||||
|
for(x = 0; x < rounds; x++){
|
||||||
|
putchar('\n');
|
||||||
|
board = getNextBoard(board, row, column);
|
||||||
|
printBoard(board, row, column);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Finished\n");
|
||||||
|
|
||||||
|
free(board);
|
||||||
|
|
||||||
|
}
|
251
assessment3gameOfLife/life2.c
Normal file
251
assessment3gameOfLife/life2.c
Normal file
@ -0,0 +1,251 @@
|
|||||||
|
/*
|
||||||
|
array of chars replaced with array of ints
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function to check 3 x 3 grid around cell defined by co-ordinates given by
|
||||||
|
the arguments "row" and "column" for live neighbours
|
||||||
|
*/
|
||||||
|
int checkNeighbours(int **board, int row, int column){
|
||||||
|
|
||||||
|
int neighbours = 0;
|
||||||
|
|
||||||
|
int start_x = column - 1; /* Moves start co-ordinate to top left of 3 x 3 grid */
|
||||||
|
int start_y = row - 1;
|
||||||
|
int x,y;
|
||||||
|
for(y = 0; y < 3; y++){ /* Nested Loops to cycle through 3 x 3 grid */
|
||||||
|
for(x = 0; x < 3; x++){
|
||||||
|
if(board[start_y + y][start_x + x] >= 0){
|
||||||
|
neighbours++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(board[row][column] >= 0) neighbours--;
|
||||||
|
|
||||||
|
/* Remove one neighbour if given cell is alive to avoid it being counted as a neighbour */
|
||||||
|
|
||||||
|
return neighbours;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function to return an empty board array with dimensions given in arguments r and c
|
||||||
|
*/
|
||||||
|
int** getBoard(int r, int c){
|
||||||
|
|
||||||
|
r+=2;
|
||||||
|
c+=2;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Adding 2 to r and c is done to add a border of empty cells around the board
|
||||||
|
|
||||||
|
This avoids trying to access unallocated memory
|
||||||
|
*/
|
||||||
|
|
||||||
|
int i, j;
|
||||||
|
int **board;
|
||||||
|
|
||||||
|
board = (int **)malloc(r * sizeof(int *));
|
||||||
|
for(i = 0; i < r; i++){
|
||||||
|
board[i] = (int *)malloc(c * sizeof(int)); /* Fill array with arrays */
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; i < r; i++)
|
||||||
|
for(j = 0; j < c; j++)
|
||||||
|
board[i][j] = -1; /* Fills board with dead cells denoted by -1 */
|
||||||
|
|
||||||
|
return board;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function that takes board input and applies rules to it,
|
||||||
|
returning a new board and deleting the old one
|
||||||
|
*/
|
||||||
|
int** getNextBoard(int **oldboard, int r, int c){
|
||||||
|
|
||||||
|
int** board = getBoard(r, c);
|
||||||
|
|
||||||
|
r+=2;
|
||||||
|
c+=2;
|
||||||
|
|
||||||
|
int x, y, neighbour;
|
||||||
|
for(y = 1; y < r - 1; y++){ /* Nested Loops to run through whole board */
|
||||||
|
for(x = 1; x < c - 1; x++){
|
||||||
|
neighbour = checkNeighbours(oldboard, y, x);
|
||||||
|
|
||||||
|
if(oldboard[y][x] >= 0){
|
||||||
|
|
||||||
|
if(neighbour < 2) /* Rule 1 */
|
||||||
|
{
|
||||||
|
board[y][x] = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(neighbour == 2 || neighbour == 3) /* Rule 2 */
|
||||||
|
{
|
||||||
|
board[y][x] = oldboard[y][x] + 1; /* adds one to cell if staying alive */
|
||||||
|
}
|
||||||
|
|
||||||
|
if(neighbour > 3) /* Rule 3 */
|
||||||
|
{
|
||||||
|
board[y][x] = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}else{
|
||||||
|
|
||||||
|
if(neighbour == 3) /* Rule 4 */
|
||||||
|
{
|
||||||
|
board[y][x] = 0; /* 0 means new cell */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(oldboard);
|
||||||
|
return board;
|
||||||
|
}
|
||||||
|
|
||||||
|
void printBoard(int **board, int row, int column){
|
||||||
|
|
||||||
|
int x;
|
||||||
|
|
||||||
|
printf("*"); /* Top Line */
|
||||||
|
for(x = 0; x < column; x++){
|
||||||
|
printf("-");
|
||||||
|
}
|
||||||
|
printf("*\n");
|
||||||
|
|
||||||
|
|
||||||
|
int y;
|
||||||
|
for(y = 1; y < row + 1; y++){ /* Board */
|
||||||
|
printf("|");
|
||||||
|
for(x = 1; x < column + 1; x++){
|
||||||
|
/* Loop starts at 1 to take into account border around board */
|
||||||
|
|
||||||
|
if(board[y][x] >= 0){ /*if alive*/
|
||||||
|
|
||||||
|
if(board[y][x] <= 9)
|
||||||
|
printf("%i", board[y][x]);
|
||||||
|
else putchar('x');
|
||||||
|
|
||||||
|
}else printf(" "); /*if dead*/
|
||||||
|
|
||||||
|
}
|
||||||
|
printf("|\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("*"); /* Bottom Line */
|
||||||
|
for(x = 0; x < column; x++){
|
||||||
|
printf("-");
|
||||||
|
}
|
||||||
|
printf("*\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
TESTING FUNCTION FOR DEBUGGING NOT USED IN PROGRAM
|
||||||
|
|
||||||
|
prints out board with x's and spaces replaced by integers
|
||||||
|
denoting number of neighbours each cell has
|
||||||
|
*/
|
||||||
|
void printNeighbourBoard(int **board, int row, int column){
|
||||||
|
|
||||||
|
int x;
|
||||||
|
|
||||||
|
printf("*");
|
||||||
|
for(x = 0; x < column; x++){
|
||||||
|
printf("-");
|
||||||
|
}
|
||||||
|
printf("*\n");
|
||||||
|
|
||||||
|
int y;
|
||||||
|
for(y = 1; y < row + 1; y++){
|
||||||
|
printf("|");
|
||||||
|
for(x = 1; x < column + 1; x++){
|
||||||
|
printf("%i", checkNeighbours(board, y, x));
|
||||||
|
}
|
||||||
|
printf("|\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("*");
|
||||||
|
for(x = 0; x < column; x++){
|
||||||
|
printf("-");
|
||||||
|
}
|
||||||
|
printf("*\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function called at runtime to open file and fill with cells
|
||||||
|
*/
|
||||||
|
int** populateBoard(int** board, char* filename, int row, int column){
|
||||||
|
|
||||||
|
FILE* file = fopen(filename, "r");
|
||||||
|
|
||||||
|
if(file == NULL){
|
||||||
|
fprintf(stderr, "ERROR: File %s Failed To Open\n", filename);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
int cells; /* Top line gives number of cells */
|
||||||
|
fscanf(file, "%i", &cells);
|
||||||
|
|
||||||
|
int i, r, c;
|
||||||
|
for(i = 0; i < cells; i++){
|
||||||
|
fscanf(file, "%i %i", &r, &c);
|
||||||
|
|
||||||
|
if(r > row || c > column){
|
||||||
|
fprintf(stderr, "ERROR: Co-ordinate found outside Board\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
board[r + 1][c + 1] = 0;
|
||||||
|
/* +1 in each case takes into account border around board */
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(file);
|
||||||
|
|
||||||
|
return board;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(int argc, char * argv[]) {
|
||||||
|
|
||||||
|
int rounds = atoi(argv[4]);
|
||||||
|
int column = atoi(argv[2]);
|
||||||
|
int row = atoi(argv[3]);
|
||||||
|
|
||||||
|
if(rounds < 1){
|
||||||
|
fprintf(stderr, "ERROR: Positive Rounds Required\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
if(column < 1){
|
||||||
|
fprintf(stderr, "ERROR: Positive Width Required\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
if(row < 1){
|
||||||
|
fprintf(stderr, "ERROR: Positive Height Required\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ** board = getBoard(row, column); /* Create First Board */
|
||||||
|
|
||||||
|
board = populateBoard(board, argv[1], row, column); /* Fill Board */
|
||||||
|
|
||||||
|
printBoard(board, row, column); /* Print Board */
|
||||||
|
|
||||||
|
int x;
|
||||||
|
for(x = 0; x < rounds; x++){
|
||||||
|
putchar('\n');
|
||||||
|
board = getNextBoard(board, row, column);
|
||||||
|
printBoard(board, row, column);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Finished\n");
|
||||||
|
|
||||||
|
free(board);
|
||||||
|
|
||||||
|
}
|
307
assessment3gameOfLife/life3.c
Normal file
307
assessment3gameOfLife/life3.c
Normal file
@ -0,0 +1,307 @@
|
|||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function to check 3 x 3 grid around cell defined by co-ordinates given by
|
||||||
|
the arguments "row" and "column" for live neighbours
|
||||||
|
*/
|
||||||
|
int checkNeighbours(int **board, int row, int column){
|
||||||
|
|
||||||
|
int neighbours = 0;
|
||||||
|
|
||||||
|
int start_x = column - 1; /* Moves start co-ordinate to top left of 3 x 3 grid */
|
||||||
|
int start_y = row - 1;
|
||||||
|
int x,y;
|
||||||
|
for(y = 0; y < 3; y++){ /* Nested Loops to cycle through 3 x 3 grid */
|
||||||
|
for(x = 0; x < 3; x++){
|
||||||
|
if(board[start_y + y][start_x + x] >= 0){
|
||||||
|
neighbours++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(board[row][column] >= 0) neighbours--;
|
||||||
|
|
||||||
|
/* Remove one neighbour if given cell is alive to avoid it being counted as a neighbour */
|
||||||
|
|
||||||
|
return neighbours;
|
||||||
|
}
|
||||||
|
|
||||||
|
int** getBoard(int r, int c){
|
||||||
|
|
||||||
|
r+=2;
|
||||||
|
c+=2;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Adding 2 to r and c is done to add a border of empty cells around the board
|
||||||
|
|
||||||
|
This avoids trying to access unallocated memory
|
||||||
|
*/
|
||||||
|
|
||||||
|
int i, j;
|
||||||
|
int **board;
|
||||||
|
|
||||||
|
board = (int **)malloc(r * sizeof(int *));
|
||||||
|
for(i = 0; i < r; i++){
|
||||||
|
board[i] = (int *)malloc(c * sizeof(int)); /* Fill array with arrays */
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; i < r; i++)
|
||||||
|
for(j = 0; j < c; j++)
|
||||||
|
board[i][j] = -1; /* Fills board with dead cells denoted by -1 */
|
||||||
|
|
||||||
|
return board;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function that takes board input and applies rules to it,
|
||||||
|
returning a new board
|
||||||
|
*/
|
||||||
|
int** getNextBoard(int **oldboard, int r, int c){
|
||||||
|
|
||||||
|
int** board = getBoard(r, c);
|
||||||
|
|
||||||
|
r+=2;
|
||||||
|
c+=2;
|
||||||
|
|
||||||
|
int x, y, neighbour; /* Nested Loops to run through whole board */
|
||||||
|
for(y = 1; y < r - 1; y++){
|
||||||
|
for(x = 1; x < c - 1; x++){
|
||||||
|
neighbour = checkNeighbours(oldboard, y, x);
|
||||||
|
|
||||||
|
if(oldboard[y][x] >= 0){
|
||||||
|
|
||||||
|
if(neighbour < 2) /* Rule 1 */
|
||||||
|
{
|
||||||
|
board[y][x] = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(neighbour == 2 || neighbour == 3) /* Rule 2 */
|
||||||
|
{
|
||||||
|
board[y][x] = oldboard[y][x] + 1; /* adds one to cell if staying alive */
|
||||||
|
}
|
||||||
|
|
||||||
|
if(neighbour > 3) /* Rule 3 */
|
||||||
|
{
|
||||||
|
board[y][x] = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}else{
|
||||||
|
|
||||||
|
if(neighbour == 3) /* Rule 4 */
|
||||||
|
{
|
||||||
|
board[y][x] = 0; /* 0 means new cell */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//free(oldboard);
|
||||||
|
/* Board not deleted here anymore as must be saved in array for later checking for patterns */
|
||||||
|
return board;
|
||||||
|
}
|
||||||
|
|
||||||
|
void printBoard(int **board, int row, int column){
|
||||||
|
|
||||||
|
int x;
|
||||||
|
|
||||||
|
printf("*"); /* Top Line */
|
||||||
|
for(x = 0; x < column; x++){
|
||||||
|
printf("-");
|
||||||
|
}
|
||||||
|
printf("*\n");
|
||||||
|
|
||||||
|
|
||||||
|
int y;
|
||||||
|
for(y = 1; y < row + 1; y++){ /* Board */
|
||||||
|
printf("|");
|
||||||
|
for(x = 1; x < column + 1; x++){
|
||||||
|
/* Loop starts at 1 to take into account border around board */
|
||||||
|
|
||||||
|
if(board[y][x] >= 0){ /*if alive*/
|
||||||
|
|
||||||
|
if(board[y][x] <= 9)
|
||||||
|
printf("%i", board[y][x]);
|
||||||
|
else putchar('x');
|
||||||
|
|
||||||
|
}else printf(" "); /*if dead*/
|
||||||
|
}
|
||||||
|
printf("|\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("*"); /* Bottom Line */
|
||||||
|
for(x = 0; x < column; x++){
|
||||||
|
printf("-");
|
||||||
|
}
|
||||||
|
printf("*\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
TESTING FUNCTION FOR DEBUGGING NOT USED IN PROGRAM
|
||||||
|
|
||||||
|
prints out board with x's and spaces replaced by integers
|
||||||
|
denoting number of neighbours each cell has
|
||||||
|
*/
|
||||||
|
void printNeighbourBoard(int **board, int row, int column){
|
||||||
|
|
||||||
|
int x;
|
||||||
|
|
||||||
|
printf("*");
|
||||||
|
for(x = 0; x < column; x++){
|
||||||
|
printf("-");
|
||||||
|
}
|
||||||
|
printf("*\n");
|
||||||
|
|
||||||
|
int y;
|
||||||
|
for(y = 1; y < row + 1; y++){
|
||||||
|
printf("|");
|
||||||
|
for(x = 1; x < column + 1; x++){
|
||||||
|
printf("%i", checkNeighbours(board, y, x));
|
||||||
|
}
|
||||||
|
printf("|\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("*");
|
||||||
|
for(x = 0; x < column; x++){
|
||||||
|
printf("-");
|
||||||
|
}
|
||||||
|
printf("*\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function called at runtime to open file and fill with cells
|
||||||
|
*/
|
||||||
|
int** populateBoard(int** board, char* filename, int row, int column){
|
||||||
|
|
||||||
|
FILE* file = fopen(filename, "r");
|
||||||
|
|
||||||
|
if(file == NULL){
|
||||||
|
fprintf(stderr, "ERROR: File %s Failed To Open\n", filename);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
int cells; /* Top line gives number of cells */
|
||||||
|
fscanf(file, "%i", &cells);
|
||||||
|
|
||||||
|
int i, r, c;
|
||||||
|
for(i = 0; i < cells; i++){
|
||||||
|
fscanf(file, "%i %i", &r, &c);
|
||||||
|
|
||||||
|
if(r > row || c > column){
|
||||||
|
fprintf(stderr, "ERROR: Co-ordinate found outside Board\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
board[r + 1][c + 1] = 0;
|
||||||
|
/* +1 in each case takes into account border around board */
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(file);
|
||||||
|
|
||||||
|
return board;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function for checking if two boards are the same called exclusively by checkBoard
|
||||||
|
|
||||||
|
returns 0 if two boards are different
|
||||||
|
returns 1 if two boards are the same
|
||||||
|
*/
|
||||||
|
int cellChecker(int** board, int** oldboard, int row, int column){
|
||||||
|
|
||||||
|
int i, j;
|
||||||
|
for(i = 1; i < row + 1; i++){
|
||||||
|
for(j = 1; j < column + 1; j++){
|
||||||
|
if(oldboard[i][j] >= 0 && board[i][j] < 0){ /* two if statements for both ways cells can be different */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(oldboard[i][j] < 0 && board[i][j] >= 0){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function for storing and checking the last four boards for patterns
|
||||||
|
|
||||||
|
returns 0 for no pattern inbetween boards
|
||||||
|
returns period of pattern if one found
|
||||||
|
*/
|
||||||
|
int checkBoard(int** board, int row, int column){
|
||||||
|
|
||||||
|
static int** arr[4] = {NULL, NULL, NULL, NULL}; /* Array to store last 4 boards */
|
||||||
|
|
||||||
|
int x, returned;
|
||||||
|
for(x = 0; x < 4; x++){ /* Loop to check all 4 boards */
|
||||||
|
if(arr[x] != NULL){
|
||||||
|
|
||||||
|
returned = cellChecker(board, arr[x], row, column);
|
||||||
|
if(returned != 0) break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(arr[3]); /* Deletes last board, shifts all up and stores new board */
|
||||||
|
arr[3] = arr[2];
|
||||||
|
arr[2] = arr[1];
|
||||||
|
arr[1] = arr[0];
|
||||||
|
arr[0] = board;
|
||||||
|
|
||||||
|
if(returned != 0) return x + 1;
|
||||||
|
else return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(int argc, char * argv[]) {
|
||||||
|
|
||||||
|
int rounds = atoi(argv[4]);
|
||||||
|
int column = atoi(argv[2]);
|
||||||
|
int row = atoi(argv[3]);
|
||||||
|
|
||||||
|
if(rounds < 1){
|
||||||
|
fprintf(stderr, "ERROR: Positive Rounds Required\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
if(column < 1){
|
||||||
|
fprintf(stderr, "ERROR: Positive Width Required\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
if(row < 1){
|
||||||
|
fprintf(stderr, "ERROR: Positive Height Required\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ** board = getBoard(row, column); /* Create First Board */
|
||||||
|
|
||||||
|
board = populateBoard(board, argv[1], row, column); /* Fill Board */
|
||||||
|
|
||||||
|
checkBoard(board, row, column); /* Initially call check board in order to
|
||||||
|
store first board in array for later checking */
|
||||||
|
|
||||||
|
printBoard(board, row, column); /* Print Board */
|
||||||
|
|
||||||
|
int x = 0;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < rounds; i++){
|
||||||
|
putchar('\n');
|
||||||
|
board = getNextBoard(board, row, column);
|
||||||
|
printBoard(board, row, column);
|
||||||
|
x = checkBoard(board, row, column);
|
||||||
|
if(x != 0) break; /* Break if pattern found */
|
||||||
|
}
|
||||||
|
|
||||||
|
if(x != 0)printf("Period detected (%i): exiting\n", x);
|
||||||
|
else printf("Finished\n");
|
||||||
|
|
||||||
|
free(board);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user