I need to copy the defaultBankData
struct to the bank
struct repeatedly (i.e. when the user selects option 1 from the menu). However, nothing I've tried does seem to work.
I got the memcpy
idea from this community but I can't figure out why it is not allowing the data stored in defaultBankData
to be copied. It keeps crashing or simply does nothing whenever I call the GenerateBuyingSellingPrice
function. Any tips please?
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#define CURRENCIES 3
#define PRICES 2
#define ID_COL_WIDTH 4
#define DATE_COL_DAY_WIDTH 2
#define DATE_COL_MONTH_WIDTH 3
#define DATE_COL_YEAR_WIDTH 4
#define BANK_COL_NAME_WIDTH 5
const char* CURRENCY_HEADER_FORMAT_OUT = "Asss\n";
const char* BANK_DATA_HEADER_FORMAT_OUT = "%-9s%-16s%-10s%-8s%-8s%-7s%-8s%-8s%-10s\n";
typedef enum {USD = 1, GBP, CAD} CURRENCY;
typedef struct
{
int yyyy;
char mmm[3];
int dd;
} Date;
typedef struct
{
int bankId;
Date exchangeDate;
char bankName[5];
float currencyPrice[CURRENCIES][PRICES];
} Bank;
CURRENCY type(int input);
int GetPrices();
int ValidateDate(Date *userDate);
bool SaveFXSummary(char *fileName, Bank *bank, int activeBanks);
Bank *ReadFXSummary(char * fileName, int *activeBanks);
void Menu(void);
void CreateBlankData(Bank *bank, int totalBanks);
void GenerateBuyingSellingPrice(Bank *bank, int activeBanks, Date *userDate);
void DisplayFXSummary(Bank *fileData, int activeBanks);
void ShowHeadingLines(int headingLength);
int main(void)
{
srand(time(NULL));
int activeBanks = 0, totalBanks = 10, choice/*input*/, result = 0;
// CURRENCY currency;
Date userDate = {0};//instantiating date struct
Bank *bank;
Bank *fileData;
***bank = malloc(sizeof(Bank) * totalBanks);***//creates a dynamic array of struct bank
Bank blankBankData[totalBanks];
CreateBlankData(blankBankData, totalBanks);
// creates an array of struct that contains default data
***Bank defaultBankData[] =
{
{.bankId = 1001, .exchangeDate = {0,"mmm",0000}, .bankName = "JN\0", .currencyPrice = {{0, 0},{0, 0},{0, 0}}},
{.bankId = 1002, .exchangeDate = {0,"mmm",0000}, .bankName = "NCB\0", .currencyPrice = {{0, 0},{0, 0},{0, 0}}},
{.bankId = 1003, .exchangeDate = {0,"mmm",0000}, .bankName = "BNS\0", .currencyPrice = {{0, 0},{0, 0},{0, 0}}},
{.bankId = 1004, .exchangeDate = {0,"mmm",0000}, .bankName = "JMMB\0",.currencyPrice = {{0, 0},{0, 0},{0, 0}}},
};***
memcpy(bank, blankBankData, sizeof(blankBankData));//copies blankBankdata to bank struct
DisplayFXSummary(bank, totalBanks);
memcpy(bank, defaultBankData, sizeof(defaultBankData));//copies defaultBankData to bank struct
activeBanks = sizeof(bank);
/*---------------------------------------------------------------------------------------------------------------------------
MAIN PROGRAM FUNCTIONALITY MENU
---------------------------------------------------------------------------------------------------------------------------*/
do
{
Menu();
scanf("%d", &choice);
printf("\n");
switch(choice)
{
case 1:
do
{
printf("\nEnter date [dd-mmm-yyyy]: ");
scanf("--%3s-%d", &userDate.dd, userDate.mmm, &userDate.yyyy);
result = ValidateDate(&userDate);
if(result != 1) printf("Invalid date. Please try again!\n");
}while(result != 1);
GenerateBuyingSellingPrice(bank, activeBanks, &userDate);
break;
case 2:
fileData = ReadFXSummary("FXSummary.bin" ,&activeBanks);
if(fileData == NULL)
{
printf("Error reading from file.\n");
return 1;
}
printf("\nFile data retrieved successfully\n\n");
DisplayFXSummary(fileData, activeBanks);
free(fileData);
break;
}
}while(choice != 4);
return 0;
}
/*---------------------------------------------------------------------------------------------------------------------------
FUNCTION DEFINITIONS
---------------------------------------------------------------------------------------------------------------------------*/
void GenerateBuyingSellingPrice(Bank *bank, int activeBanks, Date *userDate)
{
int SPREAD = 5;
for(int i = 0; i < activeBanks; i )//iterates over list of banks
{
//adds date to file
bank[i].exchangeDate.dd = userDate->dd;
strcpy(bank[i].exchangeDate.mmm, userDate->mmm);
bank[i].exchangeDate.yyyy = userDate->yyyy;
for(int j = 0; j < CURRENCIES; j )//iterates over each currency
{
for(int k = 0; k < PRICES; k =2)//iterates over each selling price
{
bank[i].currencyPrice[j][k] = GetPrices();//assign prices
//adds spread to selling price for each currency for each bank
bank[i].currencyPrice[j][k 1] = bank[i].currencyPrice[j][k] SPREAD;
}
}
}
if(SaveFXSummary("FXSummary.bin", bank, activeBanks))
{
printf("Records saved successfully\n");
}
else
{
printf("Error writing to file.\n");
exit(1);
}
free(bank);
}//end of GenerateBuyingSellingPrice function
bool SaveFXSummary(char *fileName, Bank *bank, int activeBanks)
{
FILE *file;
file = fopen(fileName, "ab");
if(file == NULL) return false;
if(fwrite(&activeBanks, sizeof(int), 1, file)!= 1) return false;
if(fwrite(bank, sizeof(Bank), activeBanks, file) != activeBanks) return false;
if(fclose(file) == EOF) return false;
return true;
}//end of SaveFXSummary function
Bank *ReadFXSummary(char * fileName, int *activeBanks)
{
FILE *file;
file = fopen(fileName, "rb");
if(file == NULL) return NULL;
if(fread(activeBanks, sizeof(int), 1, file) != 1) return NULL;
Bank *bankData = malloc(sizeof(Bank) * *activeBanks);
if(fread(bankData, sizeof(Bank), *activeBanks, file) != *activeBanks)
{
free(bankData);
return NULL;
}
if(fclose(file) == EOF)
{
free(file);
return NULL;
}
return bankData;
}//end of ReadFXSummary function
void DisplayFXSummary(Bank *fileData, int activeBanks)
{
printf(CURRENCY_HEADER_FORMAT_OUT,"USD","GBP","CAD");
ShowHeadingLines(85);
printf(BANK_DATA_HEADER_FORMAT_OUT, "BankID", "Date", "Bank", "Ask", "Bid", "Ask", "Bid", "Ask", "Bid");
ShowHeadingLines(85);
for(int i = 0; i < activeBanks; i )
{
printf("%-.*d\t", ID_COL_WIDTH, fileData[i].bankId);
printf("%-.*d",DATE_COL_DAY_WIDTH, fileData[i].exchangeDate.dd);
printf("-%-.*s", DATE_COL_MONTH_WIDTH,fileData[i].exchangeDate.mmm);
printf("-%-.*d\t",DATE_COL_YEAR_WIDTH,fileData[i].exchangeDate.yyyy);
printf("%.*s\t",BANK_COL_NAME_WIDTH, fileData[i].bankName); /*"%5s\t"*/
for(int j = 0; j < CURRENCIES; j )
{
for(int k = 0; k < PRICES; k )
{
printf("%6.2f\t", fileData[i].currencyPrice[j][k]);
}
}
printf("\n");
}
}//end of DisplayFXSummary function
CURRENCY type(int input)
{
CURRENCY currencyType = USD;
if(input == 1) currencyType = USD;
if(input == 2) currencyType = GBP;
if(input == 3) currencyType = CAD;
return currencyType;
}//end of type function
int GetPrices()
{
int price, minPrice = 80, maxPrice = 150;
return price = rand() % (maxPrice - minPrice 1) minPrice;
}//end of GetPrices function
int ValidateDate(Date *userDate)
{
const int MAX_YR = 9999, MIN_YR = 1900;
int i, validMonth = 0, validDay = 0, validyear = 0, result = 0/*, isLeapYear = 0*/; //TODO: implement leapYear logic
int daysInMonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
char* months[] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
//evaluates whether year is leap year and change # of days for Feb to 29
if(userDate->yyyy % 400 == 0 || (userDate->yyyy % 100 != 0 && userDate->yyyy % 4 == 0))
{
daysInMonth[1] = 29;
// isLeapYear = 1;
}
for(i = 0; i < 12; i )
{
if(!strcmp(userDate->mmm, months[i]))
{
// printf("Month validated successfully!\n");
validMonth = 1;
}
}
if(validMonth == 1)
{
if(userDate->dd <= daysInMonth[i-1])
{
// printf("Day validated successfully!\n");
validDay = 1;
}
}
if(userDate->yyyy >= MIN_YR && userDate->yyyy <= MAX_YR)
{
// printf("Year validated successfully!\n");
validyear = 1;
}
if(validDay && validMonth && validyear) result = 1;
return result;
}//end of ValidateDate function
void ShowHeadingLines(int headingLength)
{
for(int i = 0; i < headingLength; i )
{
printf("-");
}
printf("\n");
}
void CreateBlankData(Bank *bank, int totalBanks)
{
for(int i = 0; i < totalBanks; i )
{
bank[i].bankId = 0;
bank[i].exchangeDate.dd = 0;
strcpy(bank[i].exchangeDate.mmm,"");
bank[i].exchangeDate.yyyy = 0;
strcpy(bank[i].bankName, "");
for(int j = 0; j < CURRENCIES; j )
{
for(int k = 0; k < PRICES; k )
{
bank[i].currencyPrice[j][k] = 0;
}
}
}
}
void Menu(void)
{
printf("\n");
ShowHeadingLines(50);
printf("Welcome to Campus Forex Brokers(CFB) System\n");
ShowHeadingLines(50);
printf("1-----> Generate Buying and Selling Price\n");
printf("2-----> Display Foreign Exchange Summary\n");
printf("3-----> Buy Foreign Exchange\n");
printf("4-----> Exit\n");
ShowHeadingLines(50);
printf("\nSelect an option [1-4]: ");
}//end of Menu function
CodePudding user response:
I figured out a trick that works. The below code includes the struct instances which creates a new instance of each default struct which I can then add more data to. Let me know if anyone wants me to share the entire code to test it for themselves and even offer a better solution. This is one version of two though.
void GenerateBuyingSellingPrice()
{
int SPREAD = 5;
char dateInput[12];
printf("\nEnter date [dd-mmm-yyyy]: ");
scanf("%s", dateInput);
Bank bank1 = {.bankId = 1001, .dateInput = "00-mmm-0000", .bankName = "JN\0", .currencyPrice = {{0, 0},{0, 0},{0, 0}}};
Bank bank2 = {.bankId = 1002, .dateInput = "00-mmm-0000", .bankName = "NCB\0", .currencyPrice = {{0, 0},{0, 0},{0, 0}}};
Bank bank3 = {.bankId = 1003, .dateInput = "00-mmm-0000", .bankName = "BNS\0", .currencyPrice = {{0, 0},{0, 0},{0, 0}}};
Bank bank4 = {.bankId = 1004, .dateInput = "00-mmm-0000", .bankName = "JMMB\0",.currencyPrice = {{0, 0},{0, 0},{0, 0}}};
strcpy(bank1.dateInput, dateInput);strcpy(bank2.dateInput, dateInput);strcpy(bank3.dateInput, dateInput);strcpy(bank4.dateInput, dateInput);
for(int j = 0; j < CURRENCIES; j )//iterates over each currency
{
for(int k = 0; k < PRICES; k =2)//iterates over each selling price
{
bank1.currencyPrice[j][k] = GetPrices();//assign prices
bank1.currencyPrice[j][k 1] = bank1.currencyPrice[j][k] SPREAD;/*adds spread to selling price for each currency for each bank*/
bank2.currencyPrice[j][k] = GetPrices();
bank2.currencyPrice[j][k 1] = bank2.currencyPrice[j][k] SPREAD;
bank3.currencyPrice[j][k] = GetPrices();
bank3.currencyPrice[j][k 1] = bank3.currencyPrice[j][k] SPREAD;
bank4.currencyPrice[j][k] = GetPrices();
bank4.currencyPrice[j][k 1] = bank4.currencyPrice[j][k] SPREAD;
}
}
SaveFXSummary(FILE_NAME, bank1);
SaveFXSummary(FILE_NAME, bank2);
SaveFXSummary(FILE_NAME, bank3);
SaveFXSummary(FILE_NAME, bank4);
printf("Records saved successfully\n");
}//end of GenerateBuyingSellingPrice function