Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * Ticker - Project by Blake Ortiz
- * January 16th, 2020
- * Util.c
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "util.h"
- // Create our tree
- tree *create_tree(void)
- {
- return NULL;
- }
- // Read the data from the file the user gives us
- void read_data(FILE *fp, char ***data, size_t *sz, size_t *cap)
- {
- int max = 64;
- int ct = 0;
- *data = calloc(1, *cap * sizeof(**data));
- printf("Start of read_data\n");
- // Fill the buf with data from the file
- char buf = fgetc(fp);
- while (buf != EOF)
- {
- char *store = malloc(max);
- // Allocate each line of the file as a string but skips \n and #
- while (buf != EOF && buf != 10 && buf != 35)
- {
- store[ct] = buf;
- ct++;
- buf = fgetc(fp);
- // Allocate more space/memory
- if (ct >= max - 1)
- {
- max *= 2;
- void *tmp = realloc(store, max * sizeof(store));
- if (tmp)
- {
- store = tmp;
- }
- // If something went wrong, free everything
- else
- {
- for (unsigned int n = 0; n < *sz; n++)
- {
- free(*data[n]);
- }
- free(*data);
- return;
- }
- }
- }
- // Add them to an array and end each with null bytes
- store[ct] = '\0';
- buf = fgetc(fp);
- ct = 0;
- (*data)[(*sz)++] = store;
- // Allocate more space/memory for the lines
- if ((*sz) >= (*cap))
- {
- (*cap) *= 2;
- void *tmp = realloc(*data, *cap * sizeof(**data));
- if (tmp)
- {
- *data = tmp;
- }
- // If something went wrong, free everything
- else
- {
- for (unsigned int n = 0; n < *sz; n++)
- {
- free(*data[n]);
- }
- free(*data);
- return;
- }
- }
- }
- printf("End of read_data\n");
- }
- // Storage for the Companies
- struct company
- {
- char symbol[6];
- size_t cents;
- char *name;
- };
- // Tree struct
- struct tree
- {
- struct company *data;
- struct tree *left;
- struct tree *right;
- };
- // Take Company info from the string
- void read_company (tree **t, char *line)
- {
- if (!t)
- {
- return;
- }
- // Variable initialization
- double value = 0.0;
- char ticker[6];
- char name[64];
- char buf[64];
- int tracker = 0;
- int t_tracker = 0;
- strcpy(name, "\0");
- strcpy(buf, "\0");
- strcpy(ticker, "\0");
- // Grab the money and the ticker
- if (sscanf(line, "%5s %1f%n", ticker, &value, &tracker) != 2)
- {
- return;
- }
- // Might want to do a verification that the information we're receiving
- // Is correct before continuing with the loop. TODO //
- // Continue from where we last were, grab the Company name
- while (sscanf(line + tracker, "%63s%n", buf, &t_tracker) > 0)
- {
- // Handling for name length issues
- if ((strlen(buf) + strlen(name)) <= 63)
- {
- strcat(name, buf);
- strcat(name, " ");
- tracker += t_tracker;
- }
- else
- {
- strncat(name, buf, 63 - strlen(name));
- name[63] = '\0';
- break;
- }
- }
- // Add all processed info the our tree
- update_tree(t, ticker, name, value);
- }
- // Update the tree as necessary
- void update_tree (tree **t, char *ticker, char *name, double value)
- {
- if (!t)
- {
- return;
- }
- // create method to search for ticker
- tree *search = search_tree(*t, ticker);
- // I should probably create a method for this so I can reuse the
- // Conversion from dollars to cents -> "10.50" to "1050"
- size_t cents = value * 100;
- size_t hold = 0;
- // If we didn't find it, add it
- if (!search)
- {
- insert_tree(t, ticker, name, value);
- return;
- }
- // Subtract the new and old value
- if (value < 0 && cents <= search->data->cents)
- {
- hold = search->data->cents - cents;
- }
- // Making sure the numbers together are less than $1,000,000
- else if ((cents + search->data->cents) <= 100000000)
- {
- hold = search->data->cents + cents;
- }
- // If we don't receive proper stock info
- else
- {
- return;
- }
- // We have to copy the data so we can place it in the new stock
- char stock_symbol[6];
- char stock_name[64];
- strncpy(stock_name, search->data->symbol, 5);
- strncpy(stock_name, search->data->name, 63);
- stock_symbol[5] = '\0';
- stock_name[63] = '\0';
- // Remove the old entry of the stock
- remove_tree(t, ticker, search->data->cents);
- // Add the new entry of the stock with updated values
- insert_tree(t, stock_symbol, stock_name, hold);
- }
- // Insert an entry to the tree
- void insert_tree(tree **t, char *symbol, char *name, size_t price)
- {
- if (!t)
- {
- return;
- }
- if (!*t)
- {
- *t = calloc(1, sizeof(**t));
- // Did our calloc work?
- if (!*t)
- {
- return;
- }
- // We need a function to create a new company struct
- struct company *new = create_company(symbol, name, price);
- // If create_company wasn't successful, free and return
- if (!new)
- {
- free(*t);
- return;
- }
- (*t)->data = new;
- return;
- }
- tree *a = *t;
- // We will have to re sort the list before printing to ascend by value
- // Use this code to make another sort method used before print
- // We will also have to make another tree to store these values and print them
- /*
- // Sorts the tree by ASCII value
- if (name < a->data->name)
- {
- insert_tree(&a->left, symbol, name, price);
- }
- else
- {
- insert_tree(&a->right, symbol, name, price);
- }
- */
- if (price <= a->data->cents)
- {
- insert_tree(&a->left, symbol, name, price);
- }
- else
- {
- insert_tree(&a->right, symbol, name, price);
- }
- }
- // Remove an entry from the tree
- void remove_tree(tree **t, char *ticker, size_t value)
- {
- // We have to check for t AND the pointer *t
- if (!t || *t)
- {
- return;
- }
- // Make a copy of our current tree
- struct tree *a = *t;
- // If both trees match in value and symbol
- if ((a->data->cents == value) && (strcmp(a->data->symbol, ticker) == 0))
- {
- // Check if there's no children
- if (!a->left && !a->right)
- {
- free(a->data->name);
- free(a->data);
- free(a);
- // Reset what *a's value is
- //*a = NULL;
- // Giving me an error
- return;
- }
- // We need to do a check for if it has only one child
- else if (!a->left || !a->right)
- {
- // You can do either left or right here, doesn't matter
- if (a->left)
- {
- *t = a->left;
- }
- else
- {
- *t = a->right;
- }
- // We want to free 'a' before we leave the function
- free(a->data->name);
- free(a->data);
- free(a);
- }
- // If the tree has BOTH children
- else
- {
- // added method to get top value to save time shifting
- tree *top = get_max(a->left);
- free(a->data->name);
- free(a->data);
- // Move the greatest to the top
- struct company *new =
- create_company(top->data->symbol,
- top->data->name,
- top->data->cents);
- // Set 'a' to what 'new' holds
- a->data = new;
- remove_tree(&a->left, top->data->symbol,
- top->data->cents);
- }
- }
- // Now we need to check for other things other than them being the same
- else if (a->data->cents < value)
- {
- remove_tree(&a->right, ticker, value);
- }
- else
- {
- remove_tree(&a->left, ticker, value);
- }
- }
- int s = 0;
- // Free and remove the entire tree
- void teardown_tree(tree *t)
- {
- printf("teardown step: %d\n", ++s);
- // Needed as we're using recursion
- if (!t)
- {
- return;
- }
- teardown_tree(t->left);
- teardown_tree(t->right);
- free(t->data->name);
- free(t->data);
- free(t);
- }
- // Get the upper-most value in the tree
- struct tree *get_max(struct tree *t)
- {
- // All we have to do is recursively call get_max until there's no right
- if (t->right)
- {
- return get_max(t->right);
- }
- else
- {
- return t;
- }
- }
- // Create a new entry for each Company we receive
- struct company *create_company(char *symbol, char *name, size_t price)
- {
- // Starting with a malloc
- struct company *new = malloc(sizeof(*new));
- if (!new)
- {
- return NULL;
- }
- // Set the stock name. Use strdup instead of malloc + stdcpy
- new->name = strdup(name);
- if (!new->name)
- {
- free(new);
- return NULL;
- }
- // Set company symbol and terminate with null
- strncpy(new->symbol, symbol, sizeof(new->symbol) - 1);
- new->symbol[sizeof(new->symbol) - 1] = '\0';
- // Set the price of the stock
- new->cents = price;
- return new;
- }
- // Print out the tree
- void print_tree(const tree *t)
- {
- if (!t)
- {
- return;
- }
- // This needs a complete rewrite - We sort by ASCII, but we need
- // to print in ascending VALUE/PRICE order
- print_tree(t->left);
- printf("%p\n", t);
- // printf("%s ", t->data->symbol);
- // printf("%zu.", t->data->cents / 100);
- // printf("%02zu", t->data->cents % 100);
- // printf("%s\n", t->data->name);
- print_tree(t->right);
- }
- // Search for an entry in the tree by Symbol (ex: AAA)
- struct tree *search_tree(struct tree *t, char *name)
- {
- if (!t)
- {
- return NULL;
- }
- struct tree *search = NULL;
- // if the passed name = the symbol we're at, return it
- if (strcmp(name, t->data->symbol) == 0)
- {
- // no point to set search = t, returning t is the same
- return t;
- }
- // compares the names ASCII values to determine if we need to go L or R
- else if (name < t->data->symbol)
- {
- if (!t->left)
- {
- return NULL;
- }
- // Recursively go through to find what we're searching for
- search = search_tree(t->left, name);
- }
- else
- {
- if (!t->right)
- {
- return NULL;
- }
- // Recursively go through to find what we're searching for
- search = search_tree(t->right, name);
- }
- // else
- // {
- // search = search_tree(t->left, name);
- // if (!search)
- // {
- // search = search_tree(t->right, name);
- // }
- // }
- // return search;
- }
- // // Shift the tree around and balance it
- // static void shift(struct tree **t)
- // {
- // struct tree *a = *t;
- // // Get the height of both sides
- // size_t l_height = get_height(a->left);
- // size_t r_height = get_height(a->right);
- // // If left is greater, and higher than one after subtraction
- // if (l_height > r_height && l_height - r_height > 1)
- // {
- // size_t ll_height = get_height(a->left->left);
- // size_t lr_height = get_height(a->left->right);
- // }
- // }
- // // Get the height of the tree
- // size_t get_height(tree *t)
- // {
- // if (!t)
- // {
- // return 0;
- // }
- // size_t l = get_height(t->left);
- // size_t r = get_height(t->right);
- // return (1 + (l > r ? l : r));
- // }
- // static void r_rotate(struct tree **t)
- // {
- // }
- // static void l_rotate(struct tree **t)
- // {
- // }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement