Lab 11/16 File I/O records, linked list.

The File Records.c

/*
	This program has some kind of BUG!!

  */


#include <stdio.h>
#include <stdlib.h>

#define FMAX 20
#define LMAX 20
#define QUIT 5

struct Employee {
	int idNum;
	char firstName[FMAX];
	char lastName[LMAX];
	struct Employee* next;
};

typedef struct Employee Employee;

typedef Employee* EmpList;

void write_record(Employee e, long pos, FILE *ofp);
Employee read_record(long pos, FILE *ifp);
Employee input_record();
void output_record(Employee record);
int main_menu();
long record_count(FILE *fptr);
long getUserNum(FILE *fptr);
EmpList createList(FILE *fptr);
void printList(EmpList l);

int main(void) {

	Employee record;
	FILE *fptr;
	long record_pos;
	int choice;
	EmpList list = NULL;

	fptr = fopen("emp2.dat", "r+");
	if (fptr == NULL) {
		fptr = fopen("emp2.dat", "w+");
	}

	record_pos = record_count(fptr);

	printf("%ld record(s)\n", record_count(fptr));

	while ( (choice = main_menu()) != QUIT) {
		switch ( choice ) {
			case 1: {//add
				record = input_record();
				write_record(record, record_pos, fptr);
				break;
			}
			case 2: { //get
				int recordNum = getUserNum(fptr);
				record = read_record(recordNum, fptr);
				output_record(record);
				break;
			}
			case 3: { //list all
				long i;
				long rec_count = record_count(fptr);
				for(i = 0; i < rec_count; i++) {
					record = read_record(i, fptr);
					output_record(record);
				}
			}
			case 4: { //create linked list
				if (list != NULL) {
					// delete nodes, recover memory!!!!
				}
				list = createList(fptr);
				printList(list);
			}
			default:
				break;
		}
	}

	//record = input_record();
	//output_record(record);

	return 0;
}

void write_record(Employee e, long pos, FILE *ofp) {

	fseek(ofp, pos * sizeof(Employee), SEEK_SET);
	fwrite(&e, sizeof(Employee), 1, ofp);

}

Employee read_record(long pos, FILE *ifp) {

	Employee record;
	
	fseek(ifp, pos * sizeof(Employee), SEEK_SET);
	fread(&record, sizeof(Employee), 1, ifp);

	return record;

}

Employee input_record() {

	Employee record;

	printf("%s", "ID Num: ");
	scanf("%d", &record.idNum); 

	printf("%s", "First Name: ");
	scanf("%s", &record.firstName); 

	printf("%s", "Last Name: ");
	scanf("%s", &record.lastName); 

	return record;
}

void output_record(Employee record) {

	printf("\n%s\n", "=====================");

	printf("%s %d\n", "ID Num:", record.idNum); 

	printf("%s %s\n", "First Name:", record.firstName);

	printf("%s %s\n", "Last Name: ", record.lastName);

	printf("%s\n", "=====================");

	return;
}

int main_menu() {

	int choice;

	printf("%s", "1) Add new record\n");
	printf("%s", "2) Get a record\n");
	printf("%s", "3) List all records\n");
	printf("%s", "4) Make linked list\n");
	printf("%s", "5) Quit\n");

	printf("%s", "\n --> ");
	scanf("%d", &choice);
	
	return choice;
}

long record_count(FILE *fptr) {

	long current_pos = ftell(fptr);
	long end_pos;

	fseek(fptr, 0, SEEK_END);
	end_pos = ftell(fptr);
	fseek(fptr, current_pos, SEEK_SET);

	return end_pos / sizeof(Employee);
}

long getUserNum(FILE *fptr) {
	
	long num = -1;
	long max_rec = record_count(fptr);

	while( num < 0 || num >= max_rec) {
		printf("%s", "What record? ");
		scanf("%ld", &num);
	}

	return num;
}

EmpList createList(FILE *fptr) {
	EmpList list = NULL;
	EmpList newEmp;
	Employee record;
	long i;
	long rec_count = record_count(fptr);

	for(i = 0; i < rec_count; i++) {
		record = read_record(i, fptr);				//read a record
		newEmp = malloc( sizeof(Employee) );		//malloc memory
		*newEmp = record;							//copy record
		newEmp->next = list;						//put at start
		list = newEmp;								//update list ptr
	}

	return list;
}

void printList(EmpList l) {
	
	while ( l != NULL ) {
		output_record( *l );
		l = l->next;
	}
}