1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247
|
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_ARGS 3
#define APP_NAME "Assignment08Part1"
#define MAX_CONTACTS 10
typedef enum { ACCT_NUM, FIRST, LAST, BAL, LPAY } IndexKey;
struct clientData
{
int acctNum;
char lastName[15];
char firstName[10];
double balance;
double lastPayAmt;
};
typedef union
{
int num;
char first[30];
char last[30];
double bal;
double lpay;
} KeyType;
typedef struct
{
KeyType key;
long filePos;
} IndexRecord;
typedef struct
{
IndexKey idxKey;
char appName[20];
int recCount;
} IndexHeader;
//struct clientData arrayOfContacts[10];
typedef struct clientData ClientData;
struct clientData clientDataArray[MAX_CONTACTS];
long fileSize(FILE *input);
int descending(const void *left, const void *right);
int main(int argc, char *argv)
{
// create clientData with default data
ClientData client = { 0, "", "", 0.0, 0.0 };
ClientData client2 = { 0, "", "", 0.0, 0.0 };
FILE *fpIndexBal;
FILE *tester; // file pointer
IndexKey indexKey;
IndexHeader indexHeader;
IndexRecord *indexRecords;
IndexRecord idxTemp;
IndexHeader idxHeader;
int indexRecordCount;
long filePos;
int readCount;
int writeCount;
int dataRecordCount;
int i = 0; // incrementer
int numOfContacts = 0;
int b = 0;
int recCount;
indexKey = BAL;
// if there isnt 3 args, then exit program
if (argc != MAX_ARGS) {
printf("Incorrect number of arguments entered.");
exit(EXIT_SUCCESS);
}
// fopen opens the file; exits if file cannot be opened
if ((tester = fopen("accounts.dat", "rb")) == NULL) {
printf("File could not be opened.\n");
}
// open index file for writing
if ((fpIndexBal = fopen("accounts.idx", "wb")) == NULL)
{
printf("ERROR - can not open/create index file.\n");
return 1;
}
dataRecordCount = fileSize(tester) / sizeof(ClientData);
printf("Data record count: %d", dataRecordCount);
indexRecords = (IndexRecord *)calloc(dataRecordCount, sizeof(IndexRecord));
// populate index header record
indexHeader.idxKey = indexKey;
strcpy(indexHeader.appName, APP_NAME);
indexHeader.recCount = dataRecordCount;
rewind(tester);
filePos = ftell(tester);
indexRecordCount = 0;
// Read first data record
readCount = fread(&client, sizeof(ClientData), 1, tester);
// Process all data records
while (!feof(tester) && (readCount == 1))
{
// populate index record from data record
indexRecords[indexRecordCount].key.bal = client.balance;
indexRecords[indexRecordCount].filePos = filePos;
// added a record - increment to next element
indexRecordCount++;
// store file pos before next read advances it
filePos = ftell(tester);
// read next record
readCount = fread(&client, sizeof(ClientData), 1, tester);
}
// Sort array of index records in memory
// based on return value of compare function
qsort(indexRecords, indexRecordCount, sizeof(IndexRecord), descending);
printf("Index Header Size: %d\nIndex Record Size: %d\n\n"
, sizeof(IndexHeader), sizeof(IndexRecord));
printf("Creating Index File\n");
// write Index Header to file
writeCount = fwrite(&indexHeader, sizeof(IndexHeader), 1, fpIndexBal);
// Write Index Records to file
writeCount = fwrite(indexRecords, sizeof(IndexRecord), indexRecordCount, fpIndexBal);
printf("%d Records Processed\n", writeCount);
printf("\nFileSize: %d\n\n", fileSize(fpIndexBal));
// release this memory and set it free
free(indexRecords);
// close files
//fclose(tester);
fclose(fpIndexBal);
// ------------------test reading index-------------------------
// open index file for READING
if ((fpIndexBal = fopen("accounts.idx", "rb")) == NULL)
{
printf("ERROR - can not open/create index file.\n");
return 1;
}
// prints column headers
printf("%-15s%-15s%-15s%-15s%-15s\n"
, "Account #"
, "First Name"
, "Last Name"
, "Balance"
, "Last Payment");
//rewind(fpIndexBal);
recCount = fileSize(tester) / sizeof(ClientData);
// read header record in index file
readCount = fread(&idxHeader, sizeof(IndexHeader), 1, fpIndexBal);
// read first index record
readCount = fread(&idxTemp, sizeof(IndexRecord), 1, fpIndexBal);
// continue processing all index records
while ((!feof(fpIndexBal)) && (readCount == 1))
{
// seek record in data file based on file position
// stored in previously read index record
if (fseek(tester, idxTemp.filePos, SEEK_SET) != 0)
{
printf("Seek Error\n");
fclose(tester);
fclose(fpIndexBal);
return 1;
}
// read data record and output
fread(&client2, sizeof(ClientData), 1, tester);
printf("%-15d%-15s%-15s%-10.2lf%15.2lf\n"
, client2.acctNum
, client2.firstName
, client2.lastName
, client2.balance
, client2.lastPayAmt);
// read next index record
readCount = fread(&idxTemp, sizeof(IndexRecord), 1, fpIndexBal);
// reposition data file.
fseek(tester, idxTemp.filePos, SEEK_CUR);
}
//open index file
_getch();
return 0;
}
long fileSize(FILE *input)
{
long orgPos;
long startPos;
long endPos;
orgPos = ftell(input); // save orig file position
rewind(input);
startPos = ftell(input);
fseek(input, 0, SEEK_END);
endPos = ftell(input);
fseek(input, orgPos, SEEK_SET); // restore orig position
return(endPos - startPos);
}
int descending(const void *left, const void *right)
{
int retVal = 0;
IndexRecord *index1 = (IndexRecord*)left;
IndexRecord *index2 = (IndexRecord*)right;
if ((index1->key.bal) > (index2->key.bal))
{
retVal = 1;
}
else if ((index1->key.bal) < (index2->key.bal))
{
retVal = -1;
}
// printf("desc called\n");
return retVal * -1; // -1 for descending
}
|