diff --git a/src/better_read.c b/src/better_read.c new file mode 100644 index 0000000..4b01e16 --- /dev/null +++ b/src/better_read.c @@ -0,0 +1,66 @@ +#include +#include +#include +#include + +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; +} \ No newline at end of file diff --git a/src/main.c b/src/main.c index 0adff9f..4935c98 100644 --- a/src/main.c +++ b/src/main.c @@ -47,49 +47,51 @@ #define CREDIT_CARD_ID_LEN 8 #define TRANSACTION_ID_LEN 12 #define TRANSACTION_TIME_LEN 19 -#define END_CREDIT_CARDS "%%%%%%%%%%" +#define SEPERATING_LINE "%%%%%%%%%%" /* structure typedefs */ typedef struct { - char card_id[CREDIT_CARD_ID_LEN]; + char card_id[CREDIT_CARD_ID_LEN + 1]; int daily_lim; int trans_lim; } credit_card_t; typedef struct { - char trans_id[TRANSACTION_ID_LEN]; - char card_id[CREDIT_CARD_ID_LEN]; - char trans_time[TRANSACTION_TIME_LEN]; + char trans_id[TRANSACTION_ID_LEN + 1]; + char card_id[CREDIT_CARD_ID_LEN + 1]; + char trans_time[TRANSACTION_TIME_LEN + 1]; int trans_amount; + } transaction_t; /* function prototypes */ - void print_stage(int stage_num); -void stage_one(); -void stage_two(); +void stage_one(credit_card_t* one_card); +void stage_two(credit_card_t* all_cards, int* num_cards); void stage_three(); void stage_four(); -void read_one_line(); +void read_one_line(char* rtn_line); /* the main function */ int main(int argc, char *argv[]) { /* holds all the credit 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_one(); + stage_one(&all_cards[num_cards]); + num_cards++; /* stage 2: reading all credit card records */ - stage_two(); + stage_two(all_cards, &num_cards); /* stage 3: reading the transactions */ stage_three(); /* stage 4: checking for fraudulent transactions */ stage_four(); - return 0; } @@ -101,25 +103,168 @@ void print_stage(int stage_num) { 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 */ -void stage_one() { +/* reads a line of input, and extracts the information */ +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); + 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"); } /* 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); + /* 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"); } diff --git a/src/playing.c b/src/playing.c new file mode 100644 index 0000000..c31059f --- /dev/null +++ b/src/playing.c @@ -0,0 +1,70 @@ +#include +#include +#include +#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; + +} \ No newline at end of file diff --git a/src/test.c b/src/test.c index e871dbf..47378e8 100644 --- a/src/test.c +++ b/src/test.c @@ -6,91 +6,71 @@ #define CREDIT_CARD_ID_LEN 8 /* 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 trans_lim; } credit_card_t; -typedef struct { - char* str; -} words_t; - /* function prototypes */ -void stage_one(credit_card_t* all_cards, int* num_cards); -void read_one_card(credit_card_t* one_card); +void stage_one(credit_card_t* one_card); +void read_one_line(char* a_line); int main(int argc, char *argv[]) { /* 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; - stage_one(all_cards, &num_cards); + + stage_one(&all_cards[num_cards]); + num_cards += 1; free(all_cards); all_cards = NULL; 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"); - credit_card_t curr_card; - read_one_card(&curr_card); - printf("Card ID: %s\n", curr_card.card_id); - printf("Daily limit: %d\n", curr_card.daily_lim); - printf("Transaction limit: %d\n", curr_card.trans_lim); + + /* read the first line */ + char* a_card = (char*)malloc(sizeof(char)); + read_one_line(a_card); + 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"); } -/* read a line of input credit cards into one_card */ +/* read a line of input into one_line */ void -read_one_card(credit_card_t* one_card) { - int i = 0, c; - - /* 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')) { - if (i < CREDIT_CARD_ID_LEN) { - card_id_str[i++] = c; - index += 1; - } else { - break; +read_one_line(char* a_line) { + int c; + size_t index = 0, size = 0; + while (((c = getchar()) != EOF) && (c != '\n') && (c != '\r')) { + /* the first character is read */ + if (!size) { + size++; + a_line[index++] = c; + continue; } - } - card_id_str[i] = '\0'; - - /* 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; + if (size <= index) { + /* if there's not enough space, allocate some more */ + size *= 2; + a_line = realloc(a_line, size); + assert(a_line != NULL); } - } - daily_lim_str[i] = '\0'; - one_card->daily_lim = atoi(daily_lim_str); - - /* 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; + a_line[index++] = c; + } + a_line[index] = '\0'; + printf("inside:\n%s\n", a_line); + printf("index = %ld\n", index); } \ No newline at end of file