Advertisement
Guest User

util.c

a guest
Jan 17th, 2020
123
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 10.30 KB | None | 0 0
  1. /*
  2.  *  Ticker - Project by Blake Ortiz
  3.  *         January 16th, 2020
  4.  *          Util.c
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include "util.h"
  11.  
  12. // Create our tree
  13. tree *create_tree(void)
  14. {
  15.     return NULL;
  16. }
  17.  
  18. // Read the data from the file the user gives us
  19. void read_data(FILE *fp, char ***data, size_t *sz, size_t *cap)
  20. {
  21.     int max = 64;
  22.     int ct = 0;
  23.    
  24.     *data = calloc(1, *cap * sizeof(**data));
  25.     printf("Start of read_data\n");
  26.     // Fill the buf with data from the file
  27.     char buf = fgetc(fp);
  28.     while (buf != EOF)
  29.     {
  30.         char *store = malloc(max);
  31.         // Allocate each line of the file as a string but skips \n and #
  32.         while (buf != EOF && buf != 10 && buf != 35)
  33.         {
  34.             store[ct] = buf;
  35.             ct++;
  36.             buf = fgetc(fp);
  37.            
  38.             // Allocate more space/memory
  39.             if (ct >= max - 1)
  40.             {
  41.                 max *= 2;
  42.                 void *tmp = realloc(store, max * sizeof(store));
  43.                
  44.                 if (tmp)
  45.                 {
  46.                     store = tmp;
  47.                 }
  48.                 // If something went wrong, free everything
  49.                 else
  50.                 {
  51.                     for (unsigned int n = 0; n < *sz; n++)
  52.                     {
  53.                         free(*data[n]);
  54.                     }
  55.                    
  56.                     free(*data);
  57.                     return;
  58.                 }
  59.             }
  60.         }            
  61.         // Add them to an array and end each with null bytes
  62.         store[ct] = '\0';
  63.         buf = fgetc(fp);
  64.         ct = 0;
  65.         (*data)[(*sz)++] = store;
  66.        
  67.         // Allocate more space/memory for the lines
  68.         if ((*sz) >= (*cap))
  69.         {
  70.             (*cap) *= 2;
  71.             void *tmp = realloc(*data, *cap * sizeof(**data));
  72.            
  73.             if (tmp)
  74.             {
  75.                 *data = tmp;
  76.             }
  77.             // If something went wrong, free everything
  78.             else
  79.             {
  80.                  for (unsigned int n = 0; n < *sz; n++)
  81.                     {
  82.                         free(*data[n]);
  83.                     }
  84.                    
  85.                     free(*data);
  86.                     return;
  87.             }
  88.         }
  89.     }
  90.     printf("End of read_data\n");
  91. }
  92.  
  93. // Storage for the Companies
  94. struct company
  95. {
  96.     char symbol[6];
  97.     size_t cents;
  98.     char *name;
  99. };
  100.  
  101. // Tree struct
  102. struct tree
  103. {
  104.     struct company *data;
  105.     struct tree *left;
  106.     struct tree *right;
  107. };
  108.  
  109. // Take Company info from the string
  110. void read_company (tree **t, char *line)
  111. {
  112.     if (!t)
  113.     {
  114.         return;
  115.     }
  116.     // Variable initialization
  117.     double value = 0.0;
  118.     char ticker[6];
  119.     char name[64];
  120.     char buf[64];
  121.     int tracker = 0;
  122.     int t_tracker = 0;
  123.     strcpy(name, "\0");
  124.     strcpy(buf, "\0");
  125.     strcpy(ticker, "\0");
  126.    
  127.     // Grab the money and the ticker
  128.     if (sscanf(line, "%5s %1f%n", ticker, &value, &tracker) != 2)
  129.     {
  130.         return;
  131.     }
  132.    
  133.     // Might want to do a verification that the information we're receiving
  134.     // Is correct before continuing with the loop. TODO //
  135.  
  136.     // Continue from where we last were, grab the Company name
  137.     while (sscanf(line + tracker, "%63s%n", buf, &t_tracker) > 0)
  138.     {
  139.         // Handling for name length issues
  140.         if ((strlen(buf) + strlen(name)) <= 63)
  141.         {
  142.             strcat(name, buf);
  143.             strcat(name, " ");
  144.             tracker += t_tracker;
  145.         }
  146.         else
  147.         {
  148.             strncat(name, buf, 63 - strlen(name));
  149.             name[63] = '\0';
  150.             break;
  151.         }
  152.     }
  153.     // Add all processed info the our tree
  154.     update_tree(t, ticker, name, value);
  155. }
  156.  
  157. // Update the tree as necessary
  158. void update_tree (tree **t, char *ticker, char *name, double value)
  159. {
  160.     if (!t)
  161.     {
  162.         return;
  163.     }
  164.    
  165.     // create method to search for ticker
  166.     tree *search = search_tree(*t, ticker);
  167.  
  168.     // I should probably create a method for this so I can reuse the
  169.     // Conversion from dollars to cents -> "10.50" to "1050"
  170.     size_t cents = value * 100;
  171.     size_t hold = 0;
  172.  
  173.     // If we didn't find it, add it
  174.     if (!search)
  175.     {
  176.         insert_tree(t, ticker, name, value);
  177.         return;
  178.     }
  179.     // Subtract the new and old value
  180.     if (value < 0 && cents <= search->data->cents)
  181.     {
  182.         hold = search->data->cents - cents;
  183.     }
  184.     // Making sure the numbers together are less than $1,000,000
  185.     else if ((cents + search->data->cents) <= 100000000)
  186.     {
  187.         hold = search->data->cents + cents;
  188.     }
  189.     // If we don't receive proper stock info
  190.     else
  191.     {
  192.         return;
  193.     }
  194.    
  195.     // We have to copy the data so we can place it in the new stock
  196.     char stock_symbol[6];
  197.     char stock_name[64];
  198.     strncpy(stock_name, search->data->symbol, 5);
  199.     strncpy(stock_name, search->data->name, 63);
  200.     stock_symbol[5] = '\0';
  201.     stock_name[63] = '\0';
  202.  
  203.     // Remove the old entry of the stock
  204.     remove_tree(t, ticker, search->data->cents);
  205.     // Add the new entry of the stock with updated values
  206.     insert_tree(t, stock_symbol, stock_name, hold);
  207. }
  208.  
  209. // Insert an entry to the tree
  210. void insert_tree(tree **t, char *symbol, char *name, size_t price)
  211. {
  212.     if (!t)
  213.     {
  214.         return;
  215.     }  
  216.  
  217.     if (!*t)
  218.     {
  219.         *t = calloc(1, sizeof(**t));
  220.    
  221.         // Did our calloc work?
  222.         if (!*t)
  223.         {
  224.             return;
  225.         }  
  226.         // We need a function to create a new company struct
  227.         struct company *new = create_company(symbol, name, price);
  228.  
  229.         // If create_company wasn't successful, free and return
  230.         if (!new)
  231.         {
  232.             free(*t);
  233.             return;
  234.         }
  235.         (*t)->data = new;
  236.         return;
  237.     }
  238.  
  239.     tree *a = *t;
  240.  
  241.     // We will have to re sort the list before printing to ascend by value
  242.     // Use this code to make another sort method used before print
  243.     // We will also have to make another tree to store these values and print them
  244.     /*
  245.         // Sorts the tree by ASCII value
  246.         if (name < a->data->name)
  247.         {
  248.             insert_tree(&a->left, symbol, name, price);
  249.         }
  250.         else
  251.         {
  252.             insert_tree(&a->right, symbol, name, price);
  253.     }
  254.     */
  255.     if (price <= a->data->cents)
  256.         {
  257.             insert_tree(&a->left, symbol, name, price);
  258.         }
  259.         else
  260.         {
  261.             insert_tree(&a->right, symbol, name, price);
  262.         }
  263.    
  264.    
  265.  
  266. }
  267.  
  268. // Remove an entry from the tree
  269. void remove_tree(tree **t, char *ticker, size_t value)
  270. {
  271.     // We have to check for t AND the pointer *t
  272.     if (!t || *t)
  273.     {
  274.         return;
  275.     }
  276.    
  277.     // Make a copy of our current tree
  278.     struct tree *a = *t;
  279.  
  280.     // If both trees match in value and symbol
  281.     if ((a->data->cents == value) && (strcmp(a->data->symbol, ticker) == 0))
  282.     {
  283.         // Check if there's no children
  284.         if (!a->left && !a->right)
  285.         {
  286.             free(a->data->name);
  287.             free(a->data);
  288.             free(a);
  289.             // Reset what *a's value is
  290.             //*a = NULL;
  291.             // Giving me an error
  292.             return;
  293.         }
  294.         // We need to do a check for if it has only one child
  295.         else if (!a->left || !a->right)
  296.         {
  297.             // You can do either left or right here, doesn't matter
  298.             if (a->left)
  299.             {
  300.                 *t = a->left;
  301.             }
  302.             else
  303.             {
  304.                 *t = a->right;
  305.             }
  306.  
  307.             // We want to free 'a' before we leave the function
  308.             free(a->data->name);
  309.             free(a->data);
  310.             free(a);
  311.         }
  312.         // If the tree has BOTH children
  313.         else
  314.         {
  315.             // added method to get top value to save time shifting
  316.             tree *top = get_max(a->left);
  317.             free(a->data->name);
  318.             free(a->data);
  319.  
  320.             // Move the greatest to the top
  321.             struct company *new =
  322.             create_company(top->data->symbol,
  323.                        top->data->name,
  324.                        top->data->cents);
  325.                        
  326.             // Set 'a' to what 'new' holds         
  327.             a->data = new;
  328.  
  329.             remove_tree(&a->left, top->data->symbol,
  330.                           top->data->cents);
  331.  
  332.         }
  333.     }
  334.     // Now we need to check for other things other than them being the same
  335.     else if (a->data->cents < value)
  336.     {
  337.         remove_tree(&a->right, ticker, value);
  338.     }
  339.     else
  340.     {
  341.         remove_tree(&a->left, ticker, value);
  342.     }
  343. }
  344.  
  345. int s = 0;
  346.  
  347. // Free and remove the entire tree
  348. void teardown_tree(tree *t)
  349. {
  350.    
  351.     printf("teardown step: %d\n", ++s);
  352.     // Needed as we're using recursion
  353.     if (!t)
  354.     {
  355.         return;
  356.     }
  357.    
  358.     teardown_tree(t->left);
  359.     teardown_tree(t->right);
  360.     free(t->data->name);
  361.     free(t->data);
  362.     free(t);
  363.  
  364. }
  365.  
  366. // Get the upper-most value in the tree
  367. struct tree *get_max(struct tree *t)
  368. {
  369.     // All we have to do is recursively call get_max until there's no right
  370.     if (t->right)
  371.     {
  372.         return get_max(t->right);
  373.     }
  374.     else
  375.     {
  376.         return t;
  377.     }
  378. }
  379.  
  380. // Create a new entry for each Company we receive
  381. struct company *create_company(char *symbol, char *name, size_t price)
  382. {
  383.     // Starting with a malloc
  384.     struct company *new = malloc(sizeof(*new));
  385.  
  386.     if (!new)
  387.     {
  388.         return NULL;
  389.     }
  390.  
  391.     // Set the stock name. Use strdup instead of malloc + stdcpy
  392.     new->name = strdup(name);
  393.  
  394.     if (!new->name)
  395.     {
  396.         free(new);
  397.         return NULL;
  398.     }
  399.  
  400.     // Set company symbol and terminate with null
  401.     strncpy(new->symbol, symbol, sizeof(new->symbol) - 1);
  402.     new->symbol[sizeof(new->symbol) - 1] = '\0';
  403.  
  404.     // Set the price of the stock
  405.     new->cents = price;
  406.    
  407.     return new;
  408. }
  409.  
  410. // Print out the tree
  411. void print_tree(const tree *t)
  412. {
  413.     if (!t)
  414.     {
  415.         return;
  416.     }
  417.     // This needs a complete rewrite -  We sort by ASCII, but we need
  418.     // to print in ascending VALUE/PRICE order
  419.     print_tree(t->left);
  420.     printf("%p\n", t);
  421.     // printf("%s ", t->data->symbol);
  422.     // printf("%zu.", t->data->cents / 100);
  423.     // printf("%02zu", t->data->cents % 100);
  424.     // printf("%s\n", t->data->name);
  425.     print_tree(t->right);
  426. }
  427.  
  428. // Search for an entry in the tree by Symbol (ex: AAA)
  429. struct tree *search_tree(struct tree *t, char *name)
  430. {
  431.     if (!t)
  432.     {
  433.         return NULL;
  434.     }
  435.    
  436.     struct tree *search = NULL;
  437.    
  438.     // if the passed name = the symbol we're at, return it
  439.     if (strcmp(name, t->data->symbol) == 0)
  440.     {
  441.         // no point to set search = t, returning t is the same
  442.         return t;
  443.     }
  444.     // compares the names ASCII values to determine if we need to go L or R
  445.     else if (name < t->data->symbol)
  446.     {  
  447.         if (!t->left)
  448.         {
  449.             return NULL;
  450.         }
  451.         // Recursively go through to find what we're searching for
  452.         search = search_tree(t->left, name);
  453.     }
  454.     else
  455.     {
  456.         if (!t->right)
  457.         {
  458.             return NULL;
  459.         }
  460.         // Recursively go through to find what we're searching for
  461.         search = search_tree(t->right, name);
  462.     }
  463.     // else
  464.     // {
  465.     //  search = search_tree(t->left, name);
  466.     //  if (!search)
  467.     //  {
  468.     //      search = search_tree(t->right, name);
  469.     //  }
  470.     // }
  471.     // return search;
  472. }
  473.  
  474. // // Shift the tree around and balance it
  475. // static void shift(struct tree **t)
  476. // {
  477. //  struct tree *a = *t;
  478.  
  479. //  // Get the height of both sides
  480. //  size_t l_height = get_height(a->left);
  481. //  size_t r_height = get_height(a->right);
  482.    
  483. //  // If left is greater, and higher than one after subtraction
  484. //  if (l_height > r_height && l_height - r_height > 1)
  485. //  {
  486. //      size_t ll_height = get_height(a->left->left);
  487. //      size_t lr_height = get_height(a->left->right);
  488. //  }
  489. // }
  490.  
  491. // // Get the height of the tree
  492. // size_t get_height(tree *t)
  493. // {
  494. //  if (!t)
  495. //  {
  496. //      return 0;
  497. //  }
  498. //  size_t l = get_height(t->left);
  499. //  size_t r = get_height(t->right);
  500.  
  501. //  return (1 + (l > r ? l : r));
  502. // }
  503.  
  504.  
  505. // static void r_rotate(struct tree **t)
  506. // {
  507.  
  508. // }
  509.  
  510.  
  511. // static void l_rotate(struct tree **t)
  512. // {
  513.  
  514. // }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement