Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NAMESIZE 30
#define NUMFIELD 4
#define EMPNUM 1
#define LNAME 2
#define FNAME 3
#define RATE 4
struct employeeRecord
{
int employeeNum;
char firstName[NAMESIZE], lastName[NAMESIZE];
double hourRate;
struct employeeRecord *nextEmp;
};
typedef struct employeeRecord employee;
void sortEmployees(employee *startPtr, int field);
void loadEmployees(char *filename, employee *start);
void deleteEmployees(employee **startPtr);
void initEmployees(employee **start);
employee* createEmployee(int num, char *lastname, char *firstname, double rate);
void printEmployees(employee *start);
int decideToSwap(int field, employee *ptr2, employee *ptr3);
int main(int argc, char *argv[])
{
int field;
employee *start;
/* Check command line arguments */
if (argc != 3)
{
printf("\nERROR - Incorrect number of arguments\n");
printf("Syntax : %s filename field\n", argv[0]);
return 1;
}
if (strspn(argv[2], "0123456789") != strlen(argv[2]))
{
printf("\nERROR - Field must be an integer value in range 1 to %d\n", NUMFIELD);
return 1;
}
field = atoi(argv[2]);
if (field < 1 || field > NUMFIELD)
{
printf("\nERROR - Field must be an integer value in range 1 to %d\n", NUMFIELD);
return 1;
}
/* run main program */
initEmployees(&start);
loadEmployees(argv[1], start); printEmployees (start);
sortEmployees(start, field);
printEmployees(start);
deleteEmployees(&start);
return 0;
}
void printEmployees(employee *start)
{
/* print the employee list */
printf("\nNumber Last Name First Name Rate\n");
printf("-------+--------------------+--------------------+-----\n");
start = start->nextEmp;
while (start->employeeNum >= 0)
{
printf("%6d %-20s %-20s %.2f\n",
start->employeeNum, start->lastName,
start->firstName, start->hourRate);
start = start->nextEmp;
}
printf("\n");
}
void sortEmployees(employee *start, int field)
{
/* use bubble sort to sort the list in field order */
int swaps;
employee *ptr1, *ptr2, *ptr3;
do
{
/* run bubble sort passes through list till no swaps done */
ptr1 = start;
ptr2 = start->nextEmp;
ptr3 = ptr2->nextEmp;
if (ptr3 == NULL) break;
swaps = 0;
while (ptr3->employeeNum >= 0)
{
/* run pass through list and do swaps if needed */
if (decideToSwap(field, ptr2, ptr3))
{
ptr1->nextEmp = ptr3;
ptr2->nextEmp = ptr3->nextEmp;
ptr3->nextEmp = ptr2;
ptr1 = ptr3;
ptr3 = ptr2->nextEmp;
swaps = 1;
}
else
{
ptr1 = ptr2;
ptr2 = ptr3;
ptr3 = ptr3->nextEmp;
}
}
}
while (swaps);
}
int decideToSwap(int field, employee *ptr2, employee *ptr3)
{
/* decide if employees need to be swaped based upon given field */
switch (field)
{
/* choose field to swap on */
case EMPNUM:
return (ptr2->employeeNum > ptr3->employeeNum);
case LNAME:
return (strcmp(ptr2->lastName, ptr3->lastName) > 0);
case FNAME:
return (strcmp(ptr2->firstName, ptr3->firstName) > 0);
case RATE:
return (ptr2->hourRate > ptr3->hourRate);
default:
printf("\nERROR - Invalid field in sorting\n");
exit(1);
}
}
void loadEmployees(char *filename, employee *start)
{
/* load emplyee records and add to linked list */
int num, status;
char lastname[NAMESIZE], firstname[NAMESIZE];
double rate;
employee *temp;
FILE *fin = fopen(filename, "r");
if (fin == NULL)
{
printf("\nERROR - Unable to access %s\n", filename);
exit(1);
}
/* read in records from file stream */
while (!feof(fin))
{
status = fscanf(fin, "%d %s %s %lf", &num, lastname, firstname, &rate);
if (status != 4)
{
/* faulty record, unless end of file */
if (!feof(fin))
{
printf("\nERROR - Corrupted record in file\n");
exit(1);
}
}
else
{
/* create employee and add to list */
temp = createEmployee(num, lastname, firstname, rate);
temp->nextEmp = start->nextEmp;
start->nextEmp = temp;
}
}
fclose(fin);
}
void deleteEmployees(employee **startPtr)
{
/* Delete all employee records in linked list */
employee *temp;
while (*startPtr != NULL)
{
temp = *startPtr;
*startPtr = temp->nextEmp;
free(temp);
}
}
void initEmployees(employee **startPtr)
{
/* initialise the employee linked list with two dummy records */
*startPtr = createEmployee(-1, " ", " ", 0.0);
(*startPtr)->nextEmp = createEmployee(-2, " ", " ", 0.0);
}
employee* createEmployee(int num, char *lastname, char *firstname, double rate)
{
/* create and initialise new employee record */
employee *temp = (employee*) malloc(sizeof(employee));
if (temp == NULL)
{
printf("\nERROR - Unable to allocate memory for employee\n");
exit(1);
}
strcpy(temp->lastName, lastname);
strcpy(temp->firstName, firstname);
temp->employeeNum = num;
temp->hourRate = rate;
temp->nextEmp = NULL;
return temp;
}