initial commit

This commit is contained in:
aj 2019-02-09 18:50:58 +00:00
commit c5f514229b
9 changed files with 2281 additions and 0 deletions

106
assessment1date/date1.c Normal file
View 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
View 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
View 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);
}

View 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;
}

View 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;
}

View 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;
}

View 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);
}

View 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);
}

View 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);
}