/*****************************************************************
//
// NAME: Yong-Sung Masuda
//
// PROJECT: 1
//
// CLASS: ICS 212
//
// INSTRUCTOR: Ravi Narayan
//
// DATE: October 21, 2021
//
// FILE: user_interface.c
//
// DESCRIPTION: Contains the driver and user interface functions
// for PROJECT 1, the banking database program.
// Calls functions defined in database.c
//
//
//
****************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "record.h"
#include "database.h"
int debugmode = 0;
void getAddress();
void flushBuffer();
/*****************************************************************
//
// Function name: main
//
// DESCRIPTION: This is the entry point for the program homework3b
// It serves as the main user interface and calls
// functions defined in database.c as well as 2
// helper functions getAddress and flushBuffer.
//
// Parameters: int argc, char *argv[]
//
//
// Return values: int
//
****************************************************************/
int main(int argc, char *argv[])
{
int i = 0;
int invalidArg = 0;
int exitEarly = 0;
int menuOption = 0;
int endLoop = 0;
int accountno = 0;
char accountnoString[25];
char name[25];
char address[50];
int addressLength = 50;
char utilityString[50];
struct record * start = NULL;
char userInput[25];
size_t inputLength;
char option1[] = "add";
char option2[] = "printall";
char option3[] = "find";
char option4[] = "delete";
char option5[] = "quit";
if(argc == 2)
{
if(strcmp(argv[1],"debug") == 0)
{
debugmode = 1;
}
else
{
printf("%s is an invalid argument. Exiting program.\n", argv[1]);
exitEarly = 1;
}
}
else if(argc > 2)
{
for(i = 1; i < argc; i++)
{
if(strcmp(argv[i],"debug") != 0)
{
invalidArg++;
}
}
if(invalidArg == 0)
{
printf("Why have you typed debug multiple times?\n");
}
if(invalidArg == 1)
{
for(i = 1; i < argc; i++)
{
if(strcmp(argv[i],"debug") != 0)
{
printf("%s is an invalid argument. Exiting program.\n", argv[i]);
}
}
}
if(invalidArg > 1)
{
for(i = 1; i < argc; i++)
{
if(strcmp(argv[i],"debug") != 0)
{
printf("%s\n", argv[i]);
}
}
printf("The above arguments are invalid. Exiting program.\n");
}
exitEarly = 1;
}
if(exitEarly == 0)
{
readfile(&start, "data.txt");
printf("\n-------------------------------------------------------------\n");
printf("| Welcome to the user interface for the database of bank x. |\n");
printf("-------------------------------------------------------------\n");
do
{
menuOption = 0;
printf("\nType all or part of a menu option and hit 'Enter'\n\n");
printf("%s: Add a record to the database.\n", option1);
printf("%s: Print all records in the database.\n", option2);
printf("%s: Find a record in the database.\n", option3);
printf("%s: Delete a record from the database.\n", option4);
printf("%s: Quit this program.\n", option5);
do
{
fgets(userInput, 25, stdin);
if(userInput[strlen(userInput) - 1] != '\n')
{
flushBuffer(userInput);
}
}
while(strcmp(userInput, "\n") == 0);
userInput[strlen(userInput) - 1] = '\0';
inputLength = strlen(userInput);
if(strncmp(userInput, option1, inputLength) == 0 && inputLength <= strlen(option1))
{
menuOption = 1;
}
else if(strncmp(userInput, option2, inputLength) == 0 && inputLength <= strlen(option2))
{
menuOption = 2;
}
else if(strncmp(userInput, option3, inputLength) == 0 && inputLength <= strlen(option3))
{
menuOption = 3;
}
else if(strncmp(userInput, option4, inputLength) == 0 && inputLength <= strlen(option4))
{
menuOption = 4;
}
else if(strncmp(userInput, option5, inputLength) == 0 && inputLength <= strlen(option5))
{
endLoop = 1;
writefile(start, "data.txt");
cleanup(&start);
}
else
{
printf("%s is an invalid input\n", userInput);
}
switch(menuOption)
{
case 1:
accountno = 0;
do
{
printf("Enter your account number: ");
fgets(accountnoString, 25, stdin);
if(accountnoString[strlen(accountnoString) - 1] != '\n')
{
flushBuffer();
}
accountnoString[strlen(accountnoString) - 1] = '\0';
accountno = atoi(accountnoString);
strcpy(utilityString, "");
sprintf(utilityString, "%d", accountno);
if(strlen(accountnoString) > 9 || accountno <= 0)
{
printf("Error. Account number must be positive and no longer than 9 digits.\n");
}
else if(strcmp(accountnoString, utilityString) != 0)
{
printf("Error. Account number must not contain spaces or any other non-numerical characters.\n");
}
}
while(strlen(accountnoString) > 9 || accountno <= 0 || strcmp(accountnoString, utilityString) != 0);
do
{
printf("Enter your full name: ");
fgets(utilityString, 50, stdin);
if(utilityString[strlen(utilityString) - 1] != '\n')
{
flushBuffer();
}
if(strlen(utilityString) <= 25)
{
utilityString[strlen(utilityString) - 1] = '\0';
strncpy(name, utilityString, 25);
}
else
{
printf("The name you have entered exceeds the character limit.\n");
}
}
while(strlen(utilityString) > 24);
printf("Type your address and hit 'Enter' twice when finished:\n");
getAddress(address, addressLength);
if(addRecord(&start, accountno, name, address) == 0)
{
printf("The record has been successfully added to the database.\n");
}
else
{
printf("The account number you entered already has an account associated to it.\n");
}
break;
case 2:
printAllRecords(start);
break;
case 3:
accountno = 0;
do
{
printf("Enter your account number: ");
fgets(accountnoString, 25, stdin);
if(accountnoString[strlen(accountnoString) - 1] != '\n')
{
flushBuffer();
}
accountnoString[strlen(accountnoString) - 1] = '\0';
accountno = atoi(accountnoString);
strcpy(utilityString, "");
sprintf(utilityString, "%d", accountno);
if(strlen(accountnoString) > 9 || accountno <= 0)
{
printf("Error. Account number must be positive and no longer than 9 digits.\n");
}
else if(strcmp(accountnoString, utilityString) != 0)
{
printf("Error. Account number must not contain spaces or any other non-numerical characters.\n");
}
}
while(strlen(accountnoString) > 9 || accountno <= 0 || strcmp(accountnoString, utilityString) != 0);
if(findRecord(start, accountno) == -1)
{
printf("No account is associated with account# %d\n", accountno);
}
break;
case 4:
accountno = 0;
do
{
printf("Enter the number of the account to be deleted : ");
fgets(accountnoString, 25, stdin);
if(accountnoString[strlen(accountnoString) - 1] != '\n')
{
flushBuffer();
}
accountnoString[strlen(accountnoString) - 1] = '\0';
accountno = atoi(accountnoString);
strcpy(utilityString, "");
sprintf(utilityString, "%d", accountno);
if(strlen(accountnoString) > 9 || accountno <= 0)
{
printf("Error. Account number must be positive and no longer than 9 digits.\n");
}
else if(strcmp(accountnoString, utilityString) != 0)
{
printf("Error. Account number must not contain spaces or any other non-numerical characters.\n");
}
}
while(strlen(accountnoString) > 9 || accountno <= 0 || strcmp(accountnoString, utilityString) != 0);
if(deleteRecord(&start, accountno) == 0)
{
printf("The record has been successfully deleted from the database.\n");
}
else
{
printf("No record has been deleted.\n");
}
break;
}
menuOption = 0;
strcpy(userInput, "");
}
while(endLoop == 0);
}
return 0;
}
/*****************************************************************
//
// Function name: getAddress
//
// DESCRIPTION: A user interface function.
// This function obtains the address input by the user.
//
// Parameters: char* address
//
//
// Return values: void
//
****************************************************************/
void getAddress(char *address, int maxLength)
{
char util[100];
strcpy(util, "");
strcpy(address, "");
if(debugmode == 1)
{
printf("\n----------***DEBUG INFO***----------\n");
printf("Function call: getAddress\n");
printf("Parameters : address = %s\n", address);
printf(" maxLength = %d\n", maxLength);
printf("------------------------------------\n\n");
}
do
{
fgets(util, 100, stdin);
if(strcmp(util, "\n") != 0)
{
if(strlen(util) + strlen(address) < maxLength)
{
strcat(address, util);
}
else
{
printf("Error. You have exceeded the maximum number of characters. \nPlease re-enter your address:\n");
strcpy(address, "");
}
}
}
while(strcmp(util, "\n") != 0);
if(address[strlen(address) - 1] == '\n')
{
address[strlen(address) - 1] = '\0';
}
}
/*****************************************************************
//
// Function name: flushBuffer
//
// DESCRIPTION: A user interface function.
// This function flushes the keyboard buffer stdin
// and is called if a user input too many
// characters.
//
//
// Parameters: none
//
//
// Return values: void
//
****************************************************************/
void flushBuffer()
{
char trash[25];
if(debugmode == 1)
{
printf("\n----------***DEBUG INFO***----------\n");
printf("Function call: flushBuffer\n");
printf("Parameters : none\n");
printf("------------------------------------\n\n");
}
do
{
fgets(trash, 25, stdin);
}
while(trash[strlen(trash) - 1] != '\n');
}
/*****************************************************************
//
// NAME: Yong-Sung Masuda
//
// PROJECT: 1
//
// CLASS: ICS 212
//
// INSTRUCTOR: Ravi Narayan
//
// DATE: October 21, 2021
//
// FILE: database.c
//
// DESCRIPTION: This file contains the definitions for the
// functions declared in database.h and called
// in user_interface.c.
//
//
//
****************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "record.h"
#include "database.h"
/*****************************************************************
//
// Function name: addRecord
//
// DESCRIPTION: Adds a record to the linked list.
//
// Parameters: struct record **pstart, int accountno,
// char *name, char *address
//
// Return values: int
//
****************************************************************/
int addRecord(struct record **pstart, int accountno, char name[],char address[])
{
int duplicateAccountno = 0;
struct record *index = *pstart;
struct record *previous = NULL;
struct record *newRecord = NULL;
if(debugmode == 1)
{
printf("\n----------***DEBUG INFO***----------\n");
printf("Function call: addRecord\n");
printf("Parameters : accountno = %d\n", accountno);
printf(" name = %s\n", name);
printf(" address = %s\n", address);
printf("------------------------------------\n\n");
}
if(*pstart == NULL)
{
newRecord = malloc(sizeof(struct record));
*pstart = newRecord;
(*newRecord).next = NULL;
(*newRecord).accountno = accountno;
if(strcmp(name, "") != 0)
{
strcpy((*newRecord).name, name);
}
else
{
strcpy((*newRecord).name, "(left blank)");
}
if(strcmp(address, "") != 0)
{
strcpy((*newRecord).address, address);
}
else
{
strcpy((*newRecord).address, "(left blank)");
}
}
else
{
while(index != NULL && (*index).accountno > accountno)
{
previous = index;
index = (*index).next;
}
if(index != NULL)
{
if((*index).accountno == accountno)
{
duplicateAccountno = -1;
}
}
if(duplicateAccountno == 0)
{
newRecord = malloc(sizeof(struct record));
(*newRecord).next = index;
(*newRecord).accountno = accountno;
if(strcmp(name, "") != 0)
{
strcpy((*newRecord).name, name);
}
else
{
strcpy((*newRecord).name, "(left blank)");
}
if(strcmp(address, "") != 0)
{
strcpy((*newRecord).address, address);
}
else
{
strcpy((*newRecord).address, "(left blank)");
}
if(previous == NULL) {
*pstart = newRecord;
}
else
{
(*previous).next = newRecord;
}
}
}
return duplicateAccountno;
}
/*****************************************************************
//
// Function name: printAllRecords
//
// DESCRIPTION: Displays the data of each record to the console.
//
// Parameters: struct record *start
//
// Return values: void
//
****************************************************************/
void printAllRecords(struct record *start)
{
struct record *index = start;
if(debugmode == 1)
{
printf("\n----------***DEBUG INFO***----------\n");
printf("Function call: printAllRecords\n");
printf("Parameters : none (except for start)\n");
printf("------------------------------------\n\n");
}
if(start != NULL)
{
printf("\n------------------------------------\n");
printf(" List of accounts at Bank x\n");
printf("------------------------------------\n\n");
}
else
{
printf("There are currently no records in the database.\n");
}
while(index != NULL)
{
printf("Account#: %d\n", (*index).accountno);
printf("Name: %s\n", (*index).name);
printf("Address:\n%s\n\n", (*index).address);
index = (*index).next;
}
printf("-------------------------------------------------------------\n");
}
/*****************************************************************
//
// Function name: findRecord
//
// DESCRIPTION: Performs a linear search on the linked list for
// a record with an account number that matches
// the one which was passed.
// Displays the information to the console if found.
//
// Parameters: struct record *start, int accountno,
//
// Return values: int
//
****************************************************************/
int findRecord(struct record *start, int accountno)
{
int returnValue = 0;
struct record *index = start;
if(debugmode == 1)
{
printf("\n----------***DEBUG INFO***----------\n");
printf("Function call: findRecord\n");
printf("Parameters : accountno = %d\n", accountno);
printf("------------------------------------\n\n");
}
while(index != NULL && (*index).accountno != accountno)
{
index = (*index).next;
}
if(index == NULL)
{
returnValue = -1;
}
else
{
printf("\n------------------------------------\n");
printf(" Search results\n");
printf("------------------------------------\n\n");
printf("Account#: %d\n", (*index).accountno);
printf("Name: %s\n", (*index).name);
printf("Address:\n%s\n", (*index).address);
}
return returnValue;
}
/*****************************************************************
//
// Function name: deleteRecord
//
// DESCRIPTION: Removes a record from the linked list and frees
// its heap space
//
// Parameters: struct record **pstart, int accountno,
//
// Return values: int
//
****************************************************************/
int deleteRecord(struct record **pstart, int accountno)
{
int returnValue = 0;
struct record *index = *pstart;
struct record *previous = NULL;
if(debugmode == 1)
{
printf("\n----------***DEBUG INFO***----------\n");
printf("Function call: deleteRecord\n");
printf("Parameters : accountno = %d\n", accountno);
printf("------------------------------------\n\n");
}
while(index != NULL && accountno != (*index).accountno)
{
previous = index;
index = (*index).next;
}
if(index == NULL)
{
returnValue = -1;
}
else
{
if(previous == NULL)
{
*pstart = (*index).next;
}
else
{
(*previous).next = (*index).next;
}
free(index);
}
return returnValue;
}
/*****************************************************************
//
// Function name: readfile
//
// DESCRIPTION: Reads a text file and stores the data on the
// heap by calling addRecord.
//
// Parameters: struct record **pstart, char *filename
//
// Return values: int
//
****************************************************************/
int readfile(struct record **pstart, char filename[])
{
int cursorPos = 0;
int lastPos = 1;
int accountno = 0;
char accountnoString[25];
char util[50];
char name[25];
char address[50] = "";
int functionSuccess = 0;
FILE *fileBuffer;
if(debugmode == 1)
{
printf("\n----------***DEBUG INFO***----------\n");
printf("Function call: readfile\n");
printf("Parameters : filename = %s\n", filename);
printf("------------------------------------\n\n");
}
fileBuffer = fopen(filename, "r");
if(fileBuffer != NULL)
{
while(cursorPos != lastPos)
{
lastPos = cursorPos;
fgets(accountnoString, 25, fileBuffer);
accountno = atoi(accountnoString);
fgets(name, 25, fileBuffer);
if(name[strlen(name) - 1] == '\n')
{
name[strlen(name) - 1] = '\0';
}
else
{
fgets(util, 25, fileBuffer);
}
do
{
fgets(util, 50, fileBuffer);
strcat(address, util);
}
while(strcmp(util, "\n") != 0 && strcmp(util,"") != 0);
address[strlen(address) - 1] = '\0';
address[strlen(address) - 1] = '\0';
if(accountno != 0)
{
addRecord(pstart, accountno, name, address);
}
cursorPos = ftell(fileBuffer);
strcpy(address, "");
strcpy(accountnoString, "");
}
fclose(fileBuffer);
}
else
{
functionSuccess = -1;
}
return functionSuccess;
}
/*****************************************************************
//
// Function name: writefile
//
// DESCRIPTION: Writes the information from the linked list to a text file
//
// Parameters: struct record *start, char *filename
//
// Return values: int
//
****************************************************************/
int writefile(struct record *start, char filename[])
{
struct record *index = start;
int functionSuccess = 0;
FILE *fileBuffer;
if(debugmode == 1)
{
printf("\n----------***DEBUG INFO***----------\n");
printf("Function call: writefile\n");
printf("Parameters : filename = %s\n", filename);
printf("------------------------------------\n\n");
}
fileBuffer = fopen(filename, "w");
if(fileBuffer != NULL && start != NULL)
{
while(index != NULL)
{
fprintf(fileBuffer, "%d\n%s\n%s\n\n", (*index).accountno, (*index).name, (*index).address);
index = (*index).next;
}
fclose(fileBuffer);
}
else
{
functionSuccess = -1;
}
return functionSuccess;
}
/*****************************************************************
//
// Function name: cleanup
//
// DESCRIPTION: Frees the heap space when called //
// Parameters: struct record **pstart
//
// Return values: none
//
****************************************************************/
void cleanup(struct record **pstart)
{
struct record *index = *pstart;
struct record *previous = NULL;
if(debugmode == 1)
{
printf("\n----------***DEBUG INFO***----------\n");
printf("Function call: cleanup\n");
printf("Parameters : none (except for &start)\n");
printf("------------------------------------\n\n");
}
while(index != NULL)
{
previous = index;
index = (*index).next;
free(previous);
}
*pstart = NULL;
}
/*****************************************************************
//
// NAME: Yong-Sung Masuda
//
// PROJECT: 1
//
// CLASS: ICS 212
//
// INSTRUCTOR: Ravi Narayan
//
// DATE: October 21, 2021
//
// FILE: database.h
//
// DESCRIPTION: This file contains the declarations for the functions
// defined in database.c
// It also contains the declaration for the global
// variable debugmode.
//
//
//
****************************************************************/
extern int debugmode;
int addRecord(struct record **, int, char[], char[]);
void printAllRecords(struct record*);
int findRecord(struct record *, int);
int deleteRecord(struct record **, int);
int readfile(struct record **, char[]);
int writefile(struct record *, char[]);
void cleanup(struct record **);
/*****************************************************************
//
// NAME: Yong-Sung Masuda
//
// PROJECT: 1
//
// CLASS: ICS 212
//
// INSTRUCTOR: Ravi Narayan
//
// DATE: October 21, 2021
//
// FILE: record.h
//
// DESCRIPTION: This is a data type created for account records.
//
//
//
****************************************************************/
struct record
{
int accountno;
char name[25];
char address[50];
struct record* next;
};
832924
yongsung
dslkfj
yongsda