Stage 1 and 2 now give correct output

This commit is contained in:
Rory Healy 2020-06-01 23:04:04 +10:00
parent aacbd56e5c
commit b5bbc46ad3
Signed by: roryhealy
GPG key ID: 0A3CBDE9C2AE672F
4 changed files with 343 additions and 82 deletions

66
src/better_read.c Normal file
View file

@ -0,0 +1,66 @@
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
void read_one_line(char* rtn_line);
int is_seperating_line(char* one_line);
int main() {
char* seperating_line = "%%%%%%%%%%";
printf("Seperating line:\n%s\n", seperating_line);
return 0;
int i = 0;
char* a_line = (char*)malloc(sizeof(char));
read_one_line(a_line);
while (!is_seperating_line(a_line)) {
printf("line %d:\n%s\n\n", i++, a_line);
read_one_line(a_line);
}
return 0;
}
/* checks if the current message is a seperating line */
int
is_seperating_line(char* one_line) {
char* seperating_line = "%%%%%%%%%%";
if (!strncmp(one_line, seperating_line, strlen(seperating_line))) {
return 1;
}
return 0;
}
/* reads one line of input into one_line */
void
read_one_line(char* rtn_line) {
int c;
/* used to keep track of the size of the input */
size_t index = 0, size = 0;
char* one_line = (char*)malloc(sizeof(char)), *temp;
while (((c = getchar()) != EOF) && (c != '\n') && (c != '\r')) {
/* reallocate space if there's not enough */
if (size <= index) {
size *= 2;
size += 1;
temp = realloc(one_line, size);
assert(temp != NULL);
one_line = temp;
}
one_line[index++] = c;
}
one_line[index] = '\0';
/* copy the input to rtn_line */
temp = realloc(rtn_line, index);
assert(temp != NULL);
rtn_line = temp;
strncpy(rtn_line, one_line, index);
/* and of course, free the allocated space */
free(one_line);
one_line = NULL;
}

View file

@ -47,49 +47,51 @@
#define CREDIT_CARD_ID_LEN 8 #define CREDIT_CARD_ID_LEN 8
#define TRANSACTION_ID_LEN 12 #define TRANSACTION_ID_LEN 12
#define TRANSACTION_TIME_LEN 19 #define TRANSACTION_TIME_LEN 19
#define END_CREDIT_CARDS "%%%%%%%%%%" #define SEPERATING_LINE "%%%%%%%%%%"
/* structure typedefs */ /* structure typedefs */
typedef struct { typedef struct {
char card_id[CREDIT_CARD_ID_LEN]; char card_id[CREDIT_CARD_ID_LEN + 1];
int daily_lim; int daily_lim;
int trans_lim; int trans_lim;
} credit_card_t; } credit_card_t;
typedef struct { typedef struct {
char trans_id[TRANSACTION_ID_LEN]; char trans_id[TRANSACTION_ID_LEN + 1];
char card_id[CREDIT_CARD_ID_LEN]; char card_id[CREDIT_CARD_ID_LEN + 1];
char trans_time[TRANSACTION_TIME_LEN]; char trans_time[TRANSACTION_TIME_LEN + 1];
int trans_amount; int trans_amount;
} transaction_t; } transaction_t;
/* function prototypes */ /* function prototypes */
void print_stage(int stage_num); void print_stage(int stage_num);
void stage_one(); void stage_one(credit_card_t* one_card);
void stage_two(); void stage_two(credit_card_t* all_cards, int* num_cards);
void stage_three(); void stage_three();
void stage_four(); void stage_four();
void read_one_line(); void read_one_line(char* rtn_line);
/* the main function */ /* the main function */
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
/* holds all the credit cards */ /* holds all the credit cards */
credit_card_t all_cards[MAX_NUM_CARDS]; credit_card_t all_cards[MAX_NUM_CARDS];
/* counts the number of credit cards read */
int num_cards = 0;
/* stage 1: reading one credit card record */ /* stage 1: reading one credit card record */
stage_one(); stage_one(&all_cards[num_cards]);
num_cards++;
/* stage 2: reading all credit card records */ /* stage 2: reading all credit card records */
stage_two(); stage_two(all_cards, &num_cards);
/* stage 3: reading the transactions */ /* stage 3: reading the transactions */
stage_three(); stage_three();
/* stage 4: checking for fraudulent transactions */ /* stage 4: checking for fraudulent transactions */
stage_four(); stage_four();
return 0; return 0;
} }
@ -101,25 +103,168 @@ void print_stage(int stage_num) {
printf("\n"); printf("\n");
} }
void read_one_line() { /* reads one line of input into one_line */
void
read_one_line(char* rtn_line) {
int c;
/* used to keep track of the size of the input */
size_t index = 0, size = 0;
char* one_line = (char*)malloc(sizeof(char)), *temp;
while (((c = getchar()) != EOF) && (c != '\n') && (c != '\r')) {
/* reallocate space if there's not enough */
if (size <= index) {
size *= 2;
size += 1;
temp = realloc(one_line, size);
if (temp == NULL) {
exit(EXIT_FAILURE);
}
one_line = temp;
}
one_line[index++] = c;
}
one_line[index] = '\0';
/* copy the input to rtn_line */
temp = realloc(rtn_line, index);
if (temp == NULL) {
exit(EXIT_FAILURE);
}
rtn_line = temp;
strncpy(rtn_line, one_line, index);
/* and of course, free the allocated space */
free(one_line);
one_line = NULL;
} }
/* stage 1: reading one credit card record */ /* reads a line of input, and extracts the information */
void stage_one() { void
read_one_card(char* one_line, credit_card_t* one_card) {
int i;
strncpy(one_card->card_id, one_line, CREDIT_CARD_ID_LEN);
one_card->card_id[CREDIT_CARD_ID_LEN] = '\0';
char* daily_lim_str = (char*)malloc(sizeof(char)), *temp;
size_t index = 0, size = 0;
for (i = CREDIT_CARD_ID_LEN + 1; one_line[i] != ' '; i++) {
/* reallocate space if there's not enough */
if (size <= index) {
size *= 2;
size += 1;
temp = realloc(daily_lim_str, size);
if (temp == NULL) {
exit(EXIT_FAILURE);
}
daily_lim_str = temp;
}
daily_lim_str[index++] = one_line[i];
}
daily_lim_str[i] = '\0';
one_card->daily_lim = atoi(daily_lim_str);
char* trans_lim_str = (char*)malloc(sizeof(char));
index = 0, size = 0;
while (one_line[++i] != '\0') {
/* reallocate space if there's not enough */
if (size <= index) {
size *= 2;
size += 1;
temp = realloc(trans_lim_str, size);
if (temp == NULL) {
exit(EXIT_FAILURE);
}
trans_lim_str = temp;
}
trans_lim_str[index++] = one_line[i];
}
trans_lim_str[i] = '\0';
one_card->trans_lim = atoi(trans_lim_str);
free(daily_lim_str);
daily_lim_str = NULL;
free(trans_lim_str);
trans_lim_str = NULL;
}
/* checks if the current message is a seperating line */
int
is_seperating_line(char* one_line) {
char* seperating_line = "%%%%%%%%%%";
if (!strncmp(one_line, seperating_line, strlen(seperating_line))) {
return 1;
}
return 0;
}
/* stage one: reading one credit card record */
void stage_one(credit_card_t* one_card) {
print_stage(STAGE_ONE); print_stage(STAGE_ONE);
char* one_line = (char*)malloc(sizeof(char));
/* read the first line into one_line */
read_one_line(one_line);
/* then break the line down into seperate parts */
read_one_card(one_line, one_card);
/* finally, print the required output */
printf("Card ID: %s\n", one_card->card_id);
printf("Daily limit: %d\n", one_card->daily_lim);
printf("Transaction limit: %d\n", one_card->trans_lim);
printf("\n"); printf("\n");
} }
/* stage 2: reading all credit card records */ /* stage 2: reading all credit card records */
void stage_two() { void stage_two(credit_card_t* all_cards, int* num_cards) {
print_stage(STAGE_TWO); print_stage(STAGE_TWO);
/* the current card being analysed */
credit_card_t curr_card;
curr_card = all_cards[0];
/* the current line being read */
char* curr_line = (char*)malloc(sizeof(char));
/* the sum of the daily limits, used for calculating the average */
int sum_daily_lim = 0;
/* keeps track of the maximum transaction limit, and which card it is */
char max_trans_limit_id[CREDIT_CARD_ID_LEN + 1];
int max_trans_limit = 0;
do {
sum_daily_lim += curr_card.daily_lim;
/* finding the max transaction limit */
if (curr_card.trans_lim > max_trans_limit) {
max_trans_limit = curr_card.trans_lim;
strncpy(max_trans_limit_id, curr_card.card_id, CREDIT_CARD_ID_LEN);
max_trans_limit_id[CREDIT_CARD_ID_LEN] = '\0';
}
/* read the next line, break if it's the seperating line */
read_one_line(curr_line);
if (is_seperating_line(curr_line)) {
break;
}
/* it's not the seperating line, therefore its another card */
read_one_card(curr_line, &curr_card);
*num_cards += 1;
all_cards[*num_cards] = curr_card;
} while (*num_cards <= MAX_NUM_CARDS);
/* finally, print the required output */
printf("Number of credit cards: %d\n", *num_cards);
printf("Average daily limit: %.2f\n", (float)sum_daily_lim / *num_cards);
printf("Card with the largest transaction limit: %s\n",
max_trans_limit_id);
free(curr_line);
curr_line = NULL;
printf("\n"); printf("\n");
} }

70
src/playing.c Normal file
View file

@ -0,0 +1,70 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 1
#define CREDIT_CARD_ID_LEN 8
struct credit_card_t {
char id[CREDIT_CARD_ID_LEN + 1];
int daily_lim;
int trans_lim;
};
void get_next_line(char* new_line);
void read_credit_card(struct credit_card_t* arr_credit_card_t, char* new_line, int* num_lines);
int main() {
struct credit_card_t arr_credit_card_t[MAX];
char new_line[100];
int num_cards = 0;
get_next_line(new_line);
read_credit_card(arr_credit_card_t, new_line, &num_cards);
printf("Card ID: %s\n", arr_credit_card_t[0].id);
printf("Daily limit: %d\n", arr_credit_card_t[0].daily_lim);
printf("Transaction limit: %d\n", arr_credit_card_t[0].trans_lim);
return 0;
}
void get_next_line(char* new_line) {
int i = 0, c;
while (((c = getchar()) != EOF) && (c != '\n') && (c != '\r')) {
new_line[i++] = c;
}
new_line[i] = '\0';
}
void read_credit_card(struct credit_card_t* arr_credit_card_t, char* new_line, int* num_lines) {
int i, daily_limit_found, daily_index = 0, trans_index = 0;
char* daily_limit_str = (char*)malloc(sizeof(daily_limit_str) + 1);
char* trans_limit_str = (char*)malloc(sizeof(trans_limit_str) + 1);
for (i = 0; new_line[i] != '\0'; i++) {
if (i < CREDIT_CARD_ID_LEN) {
arr_credit_card_t[*num_lines].id[i] = new_line[i];
} else if (i == CREDIT_CARD_ID_LEN) {
arr_credit_card_t[*num_lines].id[i++] = '\0';
continue;
} else if (!daily_limit_found) {
daily_limit_str = (char*)realloc(daily_limit_str, strlen(daily_limit_str) + 1);
daily_limit_str[daily_index++] = new_line[i];
} else if (new_line[i] == ' ') {
daily_limit_found = 1;
continue;
} else {
trans_limit_str = (char*)realloc(trans_limit_str, strlen(trans_limit_str) + 1);
trans_limit_str[trans_index++] = new_line[i];
}
}
printf("newline | %s\n", new_line);
printf("card id | %s\n", arr_credit_card_t[0].id);
printf("dailyli | %s\n", daily_limit_str);
printf("transli | %s\n", trans_limit_str);
free(trans_limit_str);
free(daily_limit_str);
trans_limit_str = NULL;
daily_limit_str = NULL;
}

View file

@ -6,91 +6,71 @@
#define CREDIT_CARD_ID_LEN 8 #define CREDIT_CARD_ID_LEN 8
/* structure typedefs */ /* structure typedefs */
typedef struct {
char card_id[CREDIT_CARD_ID_LEN]; /* stores information about a single credit card */
typedef struct credit_card_t {
char card_id[CREDIT_CARD_ID_LEN + 1];
int daily_lim; int daily_lim;
int trans_lim; int trans_lim;
} credit_card_t; } credit_card_t;
typedef struct {
char* str;
} words_t;
/* function prototypes */ /* function prototypes */
void stage_one(credit_card_t* all_cards, int* num_cards); void stage_one(credit_card_t* one_card);
void read_one_card(credit_card_t* one_card); void read_one_line(char* a_line);
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
/* all_cards will store all credit card information */ /* all_cards will store all credit card information */
credit_card_t* all_cards = (credit_card_t*)malloc(sizeof(credit_card_t)); credit_card_t* all_cards = (credit_card_t*)malloc(sizeof(all_cards));
int num_cards = 0; int num_cards = 0;
stage_one(all_cards, &num_cards);
stage_one(&all_cards[num_cards]);
num_cards += 1;
free(all_cards); free(all_cards);
all_cards = NULL; all_cards = NULL;
return 0; return 0;
} }
void stage_one(credit_card_t* all_cards, int* num_cards) { /* stage one: reading one credit card record */
void stage_one(credit_card_t* one_card) {
printf("=========================Stage 1=========================\n"); printf("=========================Stage 1=========================\n");
credit_card_t curr_card;
read_one_card(&curr_card); /* read the first line */
printf("Card ID: %s\n", curr_card.card_id); char* a_card = (char*)malloc(sizeof(char));
printf("Daily limit: %d\n", curr_card.daily_lim); read_one_line(a_card);
printf("Transaction limit: %d\n", curr_card.trans_lim); printf("\noutside:\none_line:\n%s\n", a_card);
printf("strlen(one_line) = %ld\n", strlen(a_card));
/* Then print the required output */
//printf("Card ID: %s\n", one_card->card_id);
//printf("Daily limit: %d\n", one_card->daily_lim);
//printf("Transaction limit: %d\n", one_card->trans_lim);
free(a_card);
a_card = NULL;
printf("\n"); printf("\n");
} }
/* read a line of input credit cards into one_card */ /* read a line of input into one_line */
void void
read_one_card(credit_card_t* one_card) { read_one_line(char* a_line) {
int i = 0, c; int c;
size_t index = 0, size = 0;
/* records the length of the current field */
int index = 1;
char card_id_str[CREDIT_CARD_ID_LEN];
char* daily_lim_str = (char*)malloc(index * sizeof(char) + 1);
char* trans_lim_str = (char*)malloc(index * sizeof(char) + 1);
assert(daily_lim_str != NULL && trans_lim_str != NULL);
/* read the card ID from the input line */
while (((c = getchar()) != EOF) && (c != '\n') && (c != '\r')) { while (((c = getchar()) != EOF) && (c != '\n') && (c != '\r')) {
if (i < CREDIT_CARD_ID_LEN) { /* the first character is read */
card_id_str[i++] = c; if (!size) {
index += 1; size++;
} else { a_line[index++] = c;
break; continue;
} }
if (size <= index) {
/* if there's not enough space, allocate some more */
size *= 2;
a_line = realloc(a_line, size);
assert(a_line != NULL);
} }
card_id_str[i] = '\0'; a_line[index++] = c;
/* copy the card id to one_card */
strncpy(one_card->card_id, card_id_str, CREDIT_CARD_ID_LEN);
one_card->card_id[CREDIT_CARD_ID_LEN] = '\0';
/* read the daily limit from the input line */
i = 0;
while (((c = getchar()) != EOF) && (c != '\n') && (c != '\r')) {
if (c != ' ') {
daily_lim_str[i++] = c;
index += 1;
} else {
break;
} }
} a_line[index] = '\0';
daily_lim_str[i] = '\0'; printf("inside:\n%s\n", a_line);
one_card->daily_lim = atoi(daily_lim_str); printf("index = %ld\n", index);
/* read the transaction limit from the input line */
i = 0;
while (((c = getchar()) != EOF) && (c != '\n') && (c != '\r')) {
trans_lim_str[i++] = c;
index += 1;
}
trans_lim_str[i] = '\0';
one_card->trans_lim = atoi(trans_lim_str);
free(daily_lim_str);
free(trans_lim_str);
daily_lim_str = trans_lim_str = NULL;
} }