c-将一个结构数组复制到另一个数组,然后将内容写入二进制文件



我需要重复地将defaultBankData结构复制到bank结构(即,当用户从菜单中选择选项1时(。然而,我尝试过的似乎都不起作用。

我从这个社区得到了memcpy的想法,但我不明白为什么它不允许复制存储在defaultBankData中的数据。每当我调用GenerateBuyingSellingPrice函数时,它总是崩溃或什么都不做。有什么建议吗?

#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 = "%41s%15s%15sn";
const char* BANK_DATA_HEADER_FORMAT_OUT = "%-9s%-16s%-10s%-8s%-8s%-7s%-8s%-8s%-10sn";
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",  .currencyPrice = {{0, 0},{0, 0},{0, 0}}},
{.bankId = 1002, .exchangeDate = {0,"mmm",0000}, .bankName = "NCB", .currencyPrice = {{0, 0},{0, 0},{0, 0}}},
{.bankId = 1003, .exchangeDate = {0,"mmm",0000}, .bankName = "BNS", .currencyPrice = {{0, 0},{0, 0},{0, 0}}},
{.bankId = 1004, .exchangeDate = {0,"mmm",0000}, .bankName = "JMMB",.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("%2d-%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 successfullynn");
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 successfullyn");
}
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("%-.*dt", 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("-%-.*dt",DATE_COL_YEAR_WIDTH,fileData[i].exchangeDate.yyyy);
printf("%.*st",BANK_COL_NAME_WIDTH, fileData[i].bankName); /*"%5st"*/
for(int j = 0; j < CURRENCIES; j++)
{
for(int k = 0; k < PRICES; k++)
{
printf("%6.2ft", 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) Systemn");
ShowHeadingLines(50);
printf("1-----> Generate Buying and Selling Pricen");
printf("2-----> Display Foreign Exchange Summaryn");
printf("3-----> Buy Foreign Exchangen");
printf("4-----> Exitn");
ShowHeadingLines(50);
printf("nSelect an option [1-4]: ");
}//end of Menu function

我想出了一个行之有效的技巧。下面的代码包括结构实例,它为每个默认结构创建一个新实例,然后我可以向其中添加更多数据。如果有人希望我共享整个代码,以便自己测试它,甚至提供更好的解决方案,请告诉我。不过,这是两个版本中的一个。

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",  .currencyPrice = {{0, 0},{0, 0},{0, 0}}};
Bank bank2 = {.bankId = 1002, .dateInput = "00-mmm-0000", .bankName = "NCB", .currencyPrice = {{0, 0},{0, 0},{0, 0}}};
Bank bank3 = {.bankId = 1003, .dateInput = "00-mmm-0000", .bankName = "BNS", .currencyPrice = {{0, 0},{0, 0},{0, 0}}};
Bank bank4 = {.bankId = 1004, .dateInput = "00-mmm-0000", .bankName = "JMMB",.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 successfullyn");
}//end of GenerateBuyingSellingPrice function

相关内容

最新更新