Advertisement
Guest User

Untitled

a guest
Jun 18th, 2018
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 46.14 KB | None | 0 0
  1. /**********************************************************************************************************************
  2. *     DESCRIPTION:
  3. *     Write an ANSI C program that works as follows:
  4. *        1) It gets a text file whose format entails a given number of rows, each one containing:
  5. *           product identification code (4 characters),
  6. *           name of the piece in assembly (text string),
  7. *           piece identification code (4 characters),
  8. *           time of entry in line (hours:minutes:seconds),
  9. *           time of exit in line (hours:minutes:seconds). The fields are assumed to be separated by tabs or by space.
  10. *           For instance:
  11. *           H235 Sportello_dx N246 15:20:43 15:27:55
  12. *           K542 Sportello_sx N247 10:03:10 10:15:30
  13. *           A356 Maniglia_fronte G102 18:40:11 18:52:23
  14. *        2) It loads data into a suitable tree data structure.
  15. *        3) It allows the user to choose and perform the following operations:
  16. *            (a) insertion of new input from keyboard;
  17. *            (b) deletion of existing data, selected from keyboard;
  18. *            (c) print on display of the sorted list of data, sorted by identification code of the finished product,
  19. *                or by processing time in seconds (obtained from the times of entry and exit from the line),
  20. *                chosen by the user.
  21. *
  22. *     AUTHOR: Alessandro Serafini <a.serafini21@campus.uniurb.it>
  23. *
  24. **********************************************************************************************************************/
  25.  
  26. /* Including standard libraries */
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include <string.h>
  30. #include <time.h>
  31.  
  32. /* Definition of constants */
  33. #define INPUT_FILE "input.txt"
  34.  
  35. /* Binary tree types */
  36. #define TYPE_PRODUCT_ID 0
  37. #define TYPE_PROCESS_TIME 1
  38.  
  39. #define ID_LENGTH 4
  40.  
  41. /* Structures declaration */
  42.  
  43.  
  44.  
  45.  
  46. /* Article structure */
  47. struct article
  48. {
  49.     char  *product_id;
  50.     char  *name;
  51.     char  *piece_id;
  52.     char  *time_entry;
  53.     char  *time_exit;
  54.     float process_time;
  55. };
  56.  
  57. /* List element structure */
  58. typedef struct list_article
  59. {
  60.     struct article      *article;
  61.     struct list_article *succ_p;
  62. } list_article_t;
  63.  
  64.  
  65. /* Node of binary tree structure */
  66. struct node
  67. {
  68.     struct article *item;
  69.     struct node    *left, *right;
  70. };
  71.  
  72. /* Node of list structure */
  73. struct list_node
  74. {
  75.     struct article   *item;
  76.     struct list_node *next;
  77. };
  78.  
  79. /* Declaration of functions */
  80.  
  81. /* Article functions */
  82. struct article *new_article(char *product_id,
  83.                             char *name,
  84.                             char *piece_id,
  85.                             char *time_entry,
  86.                             char *time_exit,
  87.                             float process_time);
  88.  
  89. void print_article(struct article *item);
  90.  
  91. /* Binary tree functions */
  92. struct node *load_data(const char file[],
  93.                        int type);
  94.  
  95. struct node *new_node(struct article *item);
  96.  
  97. struct node *insert(struct node *node,
  98.                     struct article *item,
  99.                     int type);
  100.  
  101. struct node *min_value_node(struct node *node);
  102.  
  103. struct node *remove_product(struct node *root,
  104.                             struct article *item,
  105.                             int type);
  106.  
  107. struct node *search_id(struct node *root,
  108.                        char *product_id);
  109.  
  110. void print_tree(struct node *root);
  111.  
  112.  
  113. /* List functions */
  114. void sorted_insert_in_list(struct list_node **head_ref,
  115.                            struct list_node *new_list_node,
  116.                            int type);
  117.  
  118. struct list_node *create_list_node(struct article *item);
  119.  
  120. void printList(struct list_node *head);
  121.  
  122. struct list_node *load_data_list(const char file[],
  123.                                  int type);
  124.  
  125. void remove_list_item(struct list_node *head,
  126.                       struct list_node *node_to_remove,
  127.                       int type);
  128.  
  129. struct list_node *search_in_list(struct list_node *head,
  130.                                  char *product_id);
  131.  
  132.  
  133. /* Time functions */
  134. void get_valid_time(char *when,
  135.                     char *bigger_then);
  136.  
  137. double get_prod_process_time(char *time_entry,
  138.                              char *time_exit);
  139.  
  140. /* General functions */
  141. void print_data(struct node *root);
  142.  
  143. void clear_buffer();
  144.  
  145. int get_valid_int(char *field_name);
  146.  
  147.  
  148. /* Main function */
  149. int main()
  150. {
  151.     printf("\n*************************\nAssembly line management\n*************************\n");
  152.    
  153.     /* Initialization of 2 binary trees, one for each type of data (product id and processing time) */
  154.     struct node *root_product_id   = load_data(INPUT_FILE,
  155.                                                TYPE_PRODUCT_ID);
  156.     struct node *root_process_time = load_data(INPUT_FILE,
  157.                                                TYPE_PROCESS_TIME);
  158.    
  159.     /* Initialization of 2 lists, one for each type of data (product id and processing time) */
  160.     struct list_node *head_product_id   = load_data_list(INPUT_FILE,
  161.                                                          TYPE_PRODUCT_ID);
  162.     struct list_node *head_process_time = load_data_list(INPUT_FILE,
  163.                                                          TYPE_PROCESS_TIME);
  164.    
  165.    
  166.     /* Check for errors during the loading of data */
  167.     if (root_product_id == NULL || root_process_time == NULL)
  168.     {
  169.         printf("Opening file error\n");
  170.     }
  171.     else
  172.     {
  173.         int choice;
  174.        
  175.         /* Menu options */
  176.         do
  177.         {
  178.             printf("\n");
  179.             printf("Choose an option:\n");
  180.             printf("1) Display items\n");
  181.             printf("2) Insert item\n");
  182.             printf("3) Remove item\n");
  183.             printf("0) Exit\n\n");
  184.             printf("Choice: ");
  185.             choice = get_valid_int("Choice"); /* Acquiring a valid integer using get_valid_int() function */
  186.             printf("\n");
  187.            
  188.             switch (choice)
  189.             {
  190.                
  191.                 case 1:
  192.                     /* Before displaying data, user must select a sort key,
  193.                      * but if the binary tree is empty, this step can be skipped */
  194.                     if (root_product_id == NULL)
  195.                     {
  196.                         printf("--------------------------------------------------------------\n");
  197.                         printf("Data set is empty\n");
  198.                         printf("--------------------------------------------------------------\n");
  199.                     }
  200.                     else
  201.                     {
  202.                         printf("Display items, ");
  203.                         printf("please choose a sort key\n");
  204.                         printf("0) Product identification code\n");
  205.                         printf("1) Processing time\n");
  206.                        
  207.                         /* Acquiring sort key and validating it */
  208.                         int sort_key;
  209.                         printf("Sort key: ");
  210.                         do
  211.                         {
  212.                             sort_key = get_valid_int("Sort key");
  213.                             if (sort_key < 0 || sort_key > 1)
  214.                             {
  215.                                 printf("Sort key %d) does not exists, try again: ",
  216.                                        sort_key);
  217.                             }
  218.                         }
  219.                         while (sort_key < 0 || sort_key > 1);
  220.                        
  221.                         /* Display data from the correct tree based on user's selected sort key */
  222.                         printf("\nData sorted by field: ");
  223.                         clock_t start_print = clock();
  224.                         switch (sort_key)
  225.                         {
  226.                             case TYPE_PRODUCT_ID:
  227.                                 printf("Product id");
  228.                                 print_data(root_product_id);
  229.                                 break;
  230.                            
  231.                             case TYPE_PROCESS_TIME:
  232.                                 printf("Processing time");
  233.                                 print_data(root_process_time);
  234.                                 break;
  235.                            
  236.                             default:
  237.                                 break;
  238.                         }
  239.                        
  240.                         clock_t end_print        = clock();
  241.                         double  time_spent_print = (double) (end_print - start_print) / CLOCKS_PER_SEC;
  242.                         printf("\nTime taken for binary tree: %f milliseconds\n\n",
  243.                                time_spent_print * 1000);
  244.                        
  245.                        
  246.                         printf("\nList sorted by field: ");
  247.                         start_print = clock();
  248.                         switch (sort_key)
  249.                         {
  250.                             case TYPE_PRODUCT_ID:
  251.                                 printf("Product id\n");
  252.                                 printList(head_product_id);
  253.                                 break;
  254.                            
  255.                             case TYPE_PROCESS_TIME:
  256.                                 printf("Processing time\n");
  257.                                 /* TODO: LA STAMPA PER PROCESS TIME NON FUNZIONA */
  258.                                 printList(head_process_time);
  259.                                 break;
  260.                            
  261.                             default:
  262.                                 break;
  263.                         }
  264.                        
  265.                         end_print        = clock();
  266.                         time_spent_print = (double) (end_print - start_print) / CLOCKS_PER_SEC;
  267.                         printf("\n\nTime taken for list: %f milliseconds\n\n",
  268.                                time_spent_print * 1000);
  269.                        
  270.                        
  271.                     }
  272.                    
  273.                     break;
  274.                
  275.                 case 2:
  276.                     printf("Insert item");
  277.                     printf("\n-------------------------------\n");
  278.                    
  279.                     char product_id[64], name[64], piece_id[64], time_entry[64], time_exit[64];
  280.                    
  281.                     /* Acquision of the new record to insert in binary tree,
  282.                      * product id is unique value so it can't be duplicated and it has a specific length,
  283.                      * that's the reason of the following checks */
  284.                     printf("Product id: ");
  285.                     int id_exists = 1;
  286.                     do
  287.                     {
  288.                         scanf("%s",
  289.                               product_id);
  290.                         if (search_id(root_product_id,
  291.                                       product_id) != NULL)
  292.                         {
  293.                             clear_buffer();
  294.                             printf("A record with product id: %s already exists, try again: ",
  295.                                    product_id);
  296.                         }
  297.                         else if (strlen(product_id) > ID_LENGTH || strlen(product_id) < ID_LENGTH)
  298.                         {
  299.                             clear_buffer();
  300.                             printf("Product id length must be of %d characters: ",
  301.                                    ID_LENGTH);
  302.                         }
  303.                         else
  304.                         {
  305.                             id_exists = 0;
  306.                         }
  307.                     }
  308.                     while (id_exists);
  309.                    
  310.                    
  311.                     printf("Name (Utilizzare gli undescore al posto degli spazi): ");
  312.                     scanf("%s",
  313.                           name);
  314.                    
  315.                    
  316.                     /* Piece id has a specific length, that's the reason of the following check */
  317.                     printf("Piece id: ");
  318.                     int is_piece_id_valid = 0;
  319.                     do
  320.                     {
  321.                         scanf("%s",
  322.                               piece_id);
  323.                         if (strlen(piece_id) > ID_LENGTH || strlen(piece_id) < ID_LENGTH)
  324.                         {
  325.                             clear_buffer();
  326.                             printf("Piece id length must be of %d characters: ",
  327.                                    ID_LENGTH);
  328.                         }
  329.                         else
  330.                         {
  331.                             is_piece_id_valid = 1;
  332.                         }
  333.                     }
  334.                     while (!is_piece_id_valid);
  335.                    
  336.                    
  337.                     /* Acquision of the time entry and time exit values. Both values ​​must have a specific format,
  338.                      * for this reason I verify the formats through the function get_valid_time */
  339.                     printf("Time entry (HH:MM:SS format): ");
  340.                     get_valid_time(time_entry,
  341.                                    time_entry);
  342.                    
  343.                     printf("Time exit (HH:MM:SS format): ");
  344.                     get_valid_time(time_exit,
  345.                                    time_entry);
  346.                    
  347.                     /* Creating new article and inserting it every binary tree */
  348.                     struct article *item = new_article(product_id,
  349.                                                        name,
  350.                                                        piece_id,
  351.                                                        time_entry,
  352.                                                        time_exit,
  353.                                                        get_prod_process_time(time_entry,
  354.                                                                              time_exit));
  355.                    
  356.                     if (item != NULL)
  357.                     {
  358.                         clock_t start_insert = clock();
  359.                        
  360.                         root_product_id   = insert(root_product_id,
  361.                                                    item,
  362.                                                    TYPE_PRODUCT_ID);
  363.                         root_process_time = insert(root_process_time,
  364.                                                    item,
  365.                                                    TYPE_PROCESS_TIME);
  366.                        
  367.                         clock_t end_insert        = clock();
  368.                         double  time_spent_insert = (double) (end_insert - start_insert) / CLOCKS_PER_SEC;
  369.                        
  370.                         print_data(root_product_id);
  371.                        
  372.                        
  373.                         printf("\n\nTime taken for binary tree: %f milliseconds",
  374.                                time_spent_insert * 1000);
  375.                        
  376.                        
  377.                        
  378.                         /* TODO: SE NE AGGIUNGO UNA PER OGNI ORDINAMENTO NON FUNZIONE */
  379.                        
  380.                         /* Start with the empty list */
  381.                         struct list_node *new_list_node = NULL;
  382.                        
  383.                         start_insert = clock();
  384.                        
  385.                         new_list_node = create_list_node(item);
  386.                         sorted_insert_in_list(&head_product_id,
  387.                                               new_list_node,
  388.                                               TYPE_PRODUCT_ID);
  389.                         /*sorted_insert_in_list(&head_process_time,
  390.                                               new_list_node,
  391.                                               TYPE_PROCESS_TIME);*/
  392.                        
  393.                         end_insert        = clock();
  394.                         time_spent_insert = (double) (end_insert - start_insert) / CLOCKS_PER_SEC;
  395.                        
  396.                         printf("\nTime taken for list: %f milliseconds\n\n",
  397.                                time_spent_insert * 1000);
  398.                        
  399.                        
  400.                         printf("Created Linked List\n");
  401.                         printList(head_product_id);
  402.                        
  403.                        
  404.                         printf("\nRecord inserted successfully\n\n");
  405.                        
  406.                     }
  407.                     else
  408.                     {
  409.                         choice = 0; /* Memory allocation error, exit the program setting the choice = 0 */
  410.                     }
  411.                    
  412.                     break;
  413.                
  414.                 case 3:
  415.                     printf("Remove item");
  416.                     print_data(root_product_id); /* Displaying data to ease the user to select the product id */
  417.                    
  418.                     /* Checking if the selected product id exists */
  419.                     char id_to_remove[64];
  420.                     printf("\nProduct id to remove: ");
  421.                     int id_not_exists = 1;
  422.                     while (id_not_exists)
  423.                     {
  424.                         scanf("%s",
  425.                               id_to_remove);
  426.                         if (search_id(root_product_id,
  427.                                       id_to_remove) == NULL)
  428.                         {
  429.                             clear_buffer();
  430.                             printf("Product id does not exist, try again: ");
  431.                         }
  432.                         else
  433.                         {
  434.                             id_not_exists = 0;
  435.                         }
  436.                     }
  437.                    
  438.                     /* Searching the node to remove by the selected product id and deleting that node from every binary tree */
  439.                     struct node *node_to_remove = search_id(root_product_id,
  440.                                                             id_to_remove);
  441.                    
  442.                     clock_t start_remove = clock();
  443.                    
  444.                     root_product_id   = remove_product(root_product_id,
  445.                                                        node_to_remove->item,
  446.                                                        TYPE_PRODUCT_ID);
  447.                     root_process_time = remove_product(root_process_time,
  448.                                                        node_to_remove->item,
  449.                                                        TYPE_PROCESS_TIME);
  450.                    
  451.                     clock_t end_remove        = clock();
  452.                     double  time_spent_remove = (double) (end_remove - start_remove) / CLOCKS_PER_SEC;
  453.                     printf("\n\nTime taken for binary tree: %f milliseconds",
  454.                            time_spent_remove * 1000);
  455.                    
  456.                    
  457.                     start_remove = clock();
  458.                    
  459.                     /* TODO: SE LO RIMUOVO DA ENTRAMBE LE LISTE MI DICE CHE L'ELEMENTO NON C'E' DOPO LA REMOVE SULLA PRIMA LISTA */
  460.                    
  461.                     struct list_node *list_node_to_remove = search_in_list(head_product_id,
  462.                                                                            id_to_remove);
  463.                    
  464.                     remove_list_item(head_product_id,
  465.                                      list_node_to_remove,
  466.                                      TYPE_PRODUCT_ID);
  467.                     /*remove_list_item(head_process_time,
  468.                                      list_node_to_remove,
  469.                                      TYPE_PROCESS_TIME);*/
  470.                    
  471.                    
  472.                     end_remove        = clock();
  473.                     time_spent_remove = (double) (end_remove - start_remove) / CLOCKS_PER_SEC;
  474.                    
  475.                     printf("\nTime taken for list: %f milliseconds\n\n",
  476.                            time_spent_remove * 1000);
  477.                    
  478.                    
  479.                     printf("Uptated Linked List\n");
  480.                     printList(head_product_id);
  481.                    
  482.                    
  483.                     printf("\nRecord removed successfully\n");
  484.                    
  485.                    
  486.                     break;
  487.                
  488.                 default:
  489.                     if (choice != 0)
  490.                     {
  491.                         printf("\nOption: %d) does not exist\n",
  492.                                choice);
  493.                     }
  494.                     break;
  495.                
  496.             }
  497.            
  498.         }
  499.         while (choice != 0);
  500.     }
  501.    
  502.     /* Memory de-allocation */
  503.     free(root_product_id);
  504.     free(root_process_time);
  505.    
  506.     return 0;
  507. }
  508.  
  509. /* Implementation of functions */
  510.  
  511. /* Article functions */
  512.  
  513. /* The function acquires the data (product_id, name, piece_id, time_entry, time_exit, process_time)
  514.  * and creates a new article, returning it.*/
  515. struct article *new_article(char *product_id,
  516.                             char *name,
  517.                             char *piece_id,
  518.                             char *time_entry,
  519.                             char *time_exit,
  520.                             float process_time)
  521. {
  522.     /* Allocating memory for the new item */
  523.     struct article *item = (struct article *) malloc(sizeof(struct article));
  524.    
  525.     /* Checking for memory allocation errors */
  526.     if (item != NULL)
  527.     {
  528.         item->product_id = malloc(strlen(product_id) + 1);
  529.         if (item->product_id == NULL)
  530.         {
  531.             item = NULL;
  532.             printf("\n[ERROR] Memory allocation failed, try to re-run the program\n");
  533.         }
  534.         else
  535.         {
  536.             strcpy(item->product_id,
  537.                    product_id);
  538.             item->name = malloc(strlen(name) + 1);
  539.             if (item->name == NULL)
  540.             {
  541.                 item = NULL;
  542.                 printf("\n[ERROR] Memory allocation failed, try to re-run the program\n");
  543.             }
  544.             else
  545.             {
  546.                 strcpy(item->name,
  547.                        name);
  548.                 item->piece_id = malloc(strlen(piece_id) + 1);
  549.                 if (item->name == NULL)
  550.                 {
  551.                     item = NULL;
  552.                     printf("\n[ERROR] Memory allocation failed, try to re-run the program\n");
  553.                 }
  554.                 else
  555.                 {
  556.                     strcpy(item->piece_id,
  557.                            piece_id);
  558.                     item->time_entry = malloc(strlen(time_entry) + 1);
  559.                     if (item->name == NULL)
  560.                     {
  561.                         item = NULL;
  562.                         printf("\n[ERROR] Memory allocation failed, try to re-run the program\n");
  563.                     }
  564.                     else
  565.                     {
  566.                         strcpy(item->time_entry,
  567.                                time_entry);
  568.                         item->time_exit = malloc(strlen(time_exit) + 1);
  569.                         if (item->name == NULL)
  570.                         {
  571.                             item = NULL;
  572.                             printf("\n[ERROR] Memory allocation failed, try to re-run the program\n");
  573.                         }
  574.                         else
  575.                         {
  576.                             strcpy(item->time_exit,
  577.                                    time_exit);
  578.                             item->process_time = process_time;
  579.                         }
  580.                     }
  581.                 }
  582.             }
  583.         }
  584.     }
  585.     else
  586.     {
  587.         printf("\n[ERROR] Memory allocation failed, try to re-run the program");
  588.     }
  589.    
  590.     return item;
  591. }
  592.  
  593. /* The function acquires the item and print its data in a formatted way */
  594. void print_article(struct article *item)
  595. {
  596.     printf("%-15s%-20s%-15s%-20s%-20s\n",
  597.            item->product_id,
  598.            item->name,
  599.            item->piece_id,
  600.            item->time_entry,
  601.            item->time_exit);
  602. }
  603.  
  604. /* Binary tree functions */
  605.  
  606. /* The function acquires the input file where the data is stored and the binary tree type to insert that data */
  607. struct node *load_data(const char file[],
  608.                        int type)
  609. {
  610.     /* Initializing tree */
  611.     struct node *root = NULL;
  612.    
  613.     /* Opening input file */
  614.     FILE *f = fopen(file,
  615.                     "r");
  616.    
  617.     /* Opening file error */
  618.     if (f != NULL)
  619.     {
  620.         char product_id[64], name[64], piece_id[64], time_entry[64], time_exit[64];
  621.        
  622.         /* Loading data from file */
  623.         while (fscanf(f,
  624.                       "%s %s %s %s %s",
  625.                       product_id,
  626.                       name,
  627.                       piece_id,
  628.                       time_entry,
  629.                       time_exit) != EOF)
  630.         {
  631.             /* Creating new article and inserting it in binary tree */
  632.             struct article *item = new_article(product_id,
  633.                                                name,
  634.                                                piece_id,
  635.                                                time_entry,
  636.                                                time_exit,
  637.                                                get_prod_process_time(time_entry,
  638.                                                                      time_exit));
  639.             if (item != NULL)
  640.             {
  641.                 root = insert(root,
  642.                               item,
  643.                               type);
  644.             }
  645.             else
  646.             {
  647.                 root = NULL;
  648.             }
  649.         }
  650.         fclose(f);
  651.     }
  652.    
  653.     return root;
  654. }
  655.  
  656. /* The function acquires the item and allocates a new node with the given data.
  657. It also initialize the node left and right pointers as NULL. Then, the node is returned. */
  658. struct node *new_node(struct article *item)
  659. {
  660.     struct node *temp = (struct node *) malloc(sizeof(struct node)); /* Allocate memory for new node */
  661.    
  662.     if (temp != NULL)
  663.     {
  664.         temp->item = item; /* Storing the item in the node */
  665.         temp->left = temp->right = NULL; /* Initialize left and right child as NULL */
  666.     }
  667.     else
  668.     {
  669.         printf("\n[ERROR] Memory allocation failed, try to re-run the program\n");
  670.     }
  671.    
  672.     return temp;
  673. }
  674.  
  675. /* The function acquires a node, an item and the type of data to insert.
  676.    Then it insert the item into the correct node, and return that node. */
  677. struct node *insert(struct node *node,
  678.                     struct article *item,
  679.                     int type)
  680. {
  681.     /* If the node is NULL, it is the node where to insert the item */
  682.     if (node == NULL)
  683.     {
  684.         node = new_node(item);
  685.     }
  686.     else
  687.     {
  688.         /* If the tree is not empty, recur down it to find the correct node to insert the given item.
  689.            For data comparison between strings, strcmp() is used to get the smaller value */
  690.        
  691.         /* The switch statement is used to compare the correct item value */
  692.         switch (type)
  693.         {
  694.             /* The logic behind the insert function is quite simple:
  695.             if the value to insert is smaller than the current node value then use recursion to insert the value in his left child.
  696.             Otherwise insert it in his right child */
  697.            
  698.             /* Only product id is unique value, so < and > are enough for values comparyson, because duplicate values are not allowed. */
  699.             case TYPE_PRODUCT_ID:
  700.                 if (strcmp(item->product_id,
  701.                            node->item->product_id) < 0)
  702.                 {
  703.                     node->left = insert(node->left,
  704.                                         item,
  705.                                         type);
  706.                 }
  707.                 else if (strcmp(item->product_id,
  708.                                 node->item->product_id) > 0)
  709.                 {
  710.                     node->right = insert(node->right,
  711.                                          item,
  712.                                          type);
  713.                 }
  714.                 break;
  715.                
  716.                 /* process time allow duplicate values, so <= and > are required for values comparyson. */
  717.             case TYPE_PROCESS_TIME:
  718.                 if (item->process_time <= node->item->process_time)
  719.                 {
  720.                     node->left = insert(node->left,
  721.                                         item,
  722.                                         type);
  723.                 }
  724.                 else if (item->process_time > node->item->process_time)
  725.                 {
  726.                     node->right = insert(node->right,
  727.                                          item,
  728.                                          type);
  729.                 }
  730.                 break;
  731.            
  732.             default:
  733.                 break;
  734.         }
  735.     }
  736.    
  737.     return node;
  738. }
  739.  
  740. /* The function acquires a node and return his smallest child */
  741. struct node *min_value_node(struct node *node)
  742. {
  743.     struct node *temp = node;
  744.    
  745.     /* Loop down the node until the leftmost child is found*/
  746.     while (temp->left != NULL)
  747.     {
  748.         temp = temp->left;
  749.     }
  750.    
  751.     return temp;
  752. }
  753.  
  754. /* The function acquires a node, an item and the type of data to remove.
  755.    Then it remove the item from the correct tree, and return that tree. */
  756. struct node *remove_product(struct node *root,
  757.                             struct article *item,
  758.                             int type)
  759. {
  760.     if (root != NULL)
  761.     {
  762.         /* The switch statement is used to compare the correct item value */
  763.         switch (type)
  764.         {
  765.             case TYPE_PRODUCT_ID:
  766.                 /* If the key to be removed is smaller than the root's key, then it lies in left subtree */
  767.                 if (strcmp(item->product_id,
  768.                            root->item->product_id) < 0)
  769.                 {
  770.                     root->left = remove_product(root->left,
  771.                                                 item,
  772.                                                 type);
  773.                 }
  774.                     /* If the key to be removed is greater than the root's key, then it lies in right subtree */
  775.                 else if (strcmp(item->product_id,
  776.                                 root->item->product_id) > 0)
  777.                 {
  778.                     root->right = remove_product(root->right,
  779.                                                  item,
  780.                                                  type);
  781.                 }
  782.                     /* If key is same as root's key, then this is the node to be removed */
  783.                 else
  784.                 {
  785.                     /* Node with only one child or no child */
  786.                     if (root->left == NULL)
  787.                     {
  788.                         struct node *temp = root->right;
  789.                         free(root);
  790.                         return temp;
  791.                     }
  792.                     else if (root->right == NULL)
  793.                     {
  794.                         struct node *temp = root->left;
  795.                         free(root);
  796.                         return temp;
  797.                     }
  798.                    
  799.                     /* Node with two children: get the smallest child the right subtree */
  800.                     struct node *temp = min_value_node(root->right);
  801.                    
  802.                     /* Copy the found node item to this node */
  803.                     root->item = temp->item;
  804.                    
  805.                     /* Deleting the found node */
  806.                     root->right = remove_product(root->right,
  807.                                                  temp->item,
  808.                                                  type);
  809.                 }
  810.                 break;
  811.             case TYPE_PROCESS_TIME:
  812.                 if (item->process_time < root->item->process_time)
  813.                 {
  814.                     root->left = remove_product(root->left,
  815.                                                 item,
  816.                                                 type);
  817.                 }
  818.                 else if (item->process_time > root->item->process_time)
  819.                 {
  820.                     root->right = remove_product(root->right,
  821.                                                  item,
  822.                                                  type);
  823.                 }
  824.                 else
  825.                 {
  826.                     /* Since process time allows duplicate values, an ID comparyson must be done to remove the right item */
  827.                     if (strcmp(item->product_id,
  828.                                root->item->product_id) == 0)
  829.                     {
  830.                         if (root->left == NULL)
  831.                         {
  832.                             struct node *temp = root->right;
  833.                             free(root);
  834.                             return temp;
  835.                         }
  836.                         else if (root->right == NULL)
  837.                         {
  838.                             struct node *temp = root->left;
  839.                             free(root);
  840.                             return temp;
  841.                         }
  842.                        
  843.                         struct node *temp = min_value_node(root->right);
  844.                         root->item  = temp->item;
  845.                         root->right = remove_product(root->right,
  846.                                                      temp->item,
  847.                                                      type);
  848.                     }
  849.                     else
  850.                     {
  851.                         /* If ID is not the same, then remov the left child of that node (since insert on left child is conditioned by <= ) */
  852.                         root->left = remove_product(root->left,
  853.                                                     item,
  854.                                                     type);
  855.                     }
  856.                 }
  857.                 break;
  858.         }
  859.     }
  860.    
  861.     return root;
  862. }
  863.  
  864. /* The function acquires the root node and the product_id of the searched element,
  865.    then search a node that has the given id. It returns the node if the element exists, NULL otherwise */
  866. struct node *search_id(struct node *root,
  867.                        char *id)
  868. {
  869.     struct node *result = NULL;
  870.    
  871.     if (root != NULL)
  872.     {
  873.         if (strcmp(root->item->product_id,
  874.                    id) == 0)
  875.         { /* Item is in root */
  876.             result = root;
  877.         }
  878.         else if (strcmp(root->item->product_id,
  879.                         id) < 0)
  880.         { /* Item->product_id is greater than root's item->product_id */
  881.             result = search_id(root->right,
  882.                                id);
  883.         }
  884.         else
  885.         {   /* Item->product_id is smaller than root's item->product_id */
  886.             result = search_id(root->left,
  887.                                id);
  888.         }
  889.     }
  890.    
  891.     return result;
  892. }
  893.  
  894. /* The function acquires the root and print its data in order */
  895. void print_tree(struct node *root)
  896. {
  897.     if (root != NULL)
  898.     {
  899.         /* Use recursion to elaborate the left child */
  900.         print_tree(root->left);
  901.         /* Elaborate node item */
  902.         print_article(root->item);
  903.         /* Use recursion to elaborate the right child */
  904.         print_tree(root->right);
  905.     }
  906. }
  907.  
  908.  
  909.  
  910.  
  911.  
  912.  
  913.  
  914. /* List functions */
  915.  
  916. /* function to insert a new_node in a list. Note that this function expects a
  917.  * pointer to head_ref as this can modify the head of the input linked list*/
  918. void sorted_insert_in_list(struct list_node **head_ref,
  919.                            struct list_node *new_list_node,
  920.                            int type)
  921. {
  922.     struct list_node *current;
  923.     /* The switch statement is used to compare the correct item value */
  924.     switch (type)
  925.     {
  926.         case TYPE_PRODUCT_ID:
  927.             /* Special case for the head end */
  928.             if (*head_ref == NULL || strcmp((*head_ref)->item->product_id,
  929.                                             new_list_node->item->product_id) > 0)
  930.             {
  931.                 new_list_node->next = *head_ref;
  932.                 *head_ref = new_list_node;
  933.             }
  934.             else
  935.             {
  936.                 /* Locate the node before the point of insertion */
  937.                 current = *head_ref;
  938.                 while (current->next != NULL &&
  939.                        strcmp(current->next->item->product_id,
  940.                               new_list_node->item->product_id) < 0)
  941.                 {
  942.                     current = current->next;
  943.                 }
  944.                 new_list_node->next = current->next;
  945.                 current->next       = new_list_node;
  946.             }
  947.             break;
  948.        
  949.         case TYPE_PROCESS_TIME:
  950.             /* Special case for the head end */
  951.             if (*head_ref == NULL || (*head_ref)->item->process_time > new_list_node->item->process_time)
  952.             {
  953.                 printf("passo1: %s",
  954.                        new_list_node->item->product_id);
  955.                 new_list_node->next = *head_ref;
  956.                 *head_ref = new_list_node;
  957.             }
  958.             else
  959.             {
  960.                 printf("passo2: %s",
  961.                        new_list_node->item->product_id);
  962.                 /* Locate the node before the point of insertion */
  963.                 current = *head_ref;
  964.                 while (current->next != NULL &&
  965.                        current->next->item->process_time < new_list_node->item->process_time)
  966.                 {
  967.                     printf("\npasso3: %s",
  968.                            new_list_node->item->product_id);
  969.                     current = current->next;
  970.                 }
  971.                 new_list_node->next = current->next;
  972.                 current->next       = new_list_node;
  973.             }
  974.             break;
  975.        
  976.         default:
  977.             break;
  978.     }
  979.    
  980.    
  981. }
  982.  
  983. /* A utility function to create a new list node */
  984. struct list_node *create_list_node(struct article *item)
  985. {
  986.     /* allocate list node */
  987.     struct list_node *new_list_node = (struct list_node *) malloc(sizeof(struct list_node));
  988.    
  989.     /* put in the data */
  990.     new_list_node->item = item;
  991.     new_list_node->next = NULL;
  992.    
  993.     return new_list_node;
  994. }
  995.  
  996. /* Function to print linked list */
  997. void printList(struct list_node *head)
  998. {
  999.     struct list_node *temp = head;
  1000.     while (temp != NULL)
  1001.     {
  1002.         printf("%s, ",
  1003.                temp->item->product_id);
  1004.         temp = temp->next;
  1005.     }
  1006. }
  1007.  
  1008. /* The function acquires the input file where the data is stored and the list type to insert that data */
  1009. struct list_node *load_data_list(const char file[],
  1010.                                  int type)
  1011. {
  1012.     /* Initializing list */
  1013.     struct list_node *head          = NULL;
  1014.     struct list_node *new_list_node = NULL;
  1015.    
  1016.    
  1017.     /* Opening input file */
  1018.     FILE *f = fopen(file,
  1019.                     "r");
  1020.    
  1021.     /* Opening file error */
  1022.     if (f != NULL)
  1023.     {
  1024.         char product_id[64], name[64], piece_id[64], time_entry[64], time_exit[64];
  1025.        
  1026.         /* Loading data from file */
  1027.         while (fscanf(f,
  1028.                       "%s %s %s %s %s",
  1029.                       product_id,
  1030.                       name,
  1031.                       piece_id,
  1032.                       time_entry,
  1033.                       time_exit) != EOF)
  1034.         {
  1035.             /* Creating new article and inserting it in binary tree */
  1036.             struct article *item = new_article(product_id,
  1037.                                                name,
  1038.                                                piece_id,
  1039.                                                time_entry,
  1040.                                                time_exit,
  1041.                                                get_prod_process_time(time_entry,
  1042.                                                                      time_exit));
  1043.             if (item != NULL)
  1044.             {
  1045.                 printf("\ntype: %d\n",
  1046.                        type);
  1047.                 new_list_node = create_list_node(item);
  1048.                 sorted_insert_in_list(&head,
  1049.                                       new_list_node,
  1050.                                       type);
  1051.             }
  1052.             else
  1053.             {
  1054.                 new_list_node = NULL;
  1055.             }
  1056.         }
  1057.         fclose(f);
  1058.     }
  1059.    
  1060.     return new_list_node;
  1061. }
  1062.  
  1063. void remove_list_item(struct list_node *head,
  1064.                       struct list_node *node_to_remove,
  1065.                       int type)
  1066. {
  1067.     /* TODO: GESTIRE ENTRAMBI GLI ORDINAMENTI */
  1068.    
  1069.     if (head->next == NULL)
  1070.     {
  1071.         printf("There is only one node. The list can't be made empty ");
  1072.     }
  1073.     else
  1074.     {
  1075.         /* When node to be deleted is head node */
  1076.         if (head == node_to_remove)
  1077.         {
  1078.             /* Copy the item of next node to head */
  1079.             head->item = head->next->item;
  1080.            
  1081.             /* store address of next node */
  1082.             node_to_remove = head->next;
  1083.            
  1084.             /* Remove the link of next node */
  1085.             head->next = head->next->next;
  1086.            
  1087.             /* free memory */
  1088.             free(node_to_remove);
  1089.            
  1090.             return;
  1091.         }
  1092.        
  1093.        
  1094.         /* When not first node, follow the normal deletion process */
  1095.        
  1096.         /* find the previous node */
  1097.         struct list_node *prev = head;
  1098.         while (prev->next != NULL && prev->next != node_to_remove)
  1099.             prev = prev->next;
  1100.        
  1101.         /* Check if node really exists in Linked List */
  1102.         if (prev->next == NULL)
  1103.         {
  1104.             printf("\n Given node is not present in Linked List");
  1105.             return;
  1106.         }
  1107.        
  1108.         /* Remove node from Linked List */
  1109.         prev->next = prev->next->next;
  1110.        
  1111.         /* Free memory */
  1112.         free(node_to_remove);
  1113.     }
  1114.     return;
  1115. }
  1116.  
  1117. /* Checks whether the value x is present in linked list */
  1118. struct list_node *search_in_list(struct list_node *head,
  1119.                                  char *product_id)
  1120. {
  1121.     /* Initialize current */
  1122.     struct list_node *current = head;
  1123.     struct list_node *result  = NULL;
  1124.     while (current != NULL)
  1125.     {
  1126.         if (strcmp(current->item->product_id,
  1127.                    product_id) == 0)
  1128.         {
  1129.             result = current;
  1130.         }
  1131.         current = current->next;
  1132.     }
  1133.     return result;
  1134. }
  1135.  
  1136.  
  1137.  
  1138.  
  1139.  
  1140.  
  1141.  
  1142. /* Time functions */
  1143.  
  1144. /* This function acquires a string and validates it in the format %H:%M:%S.
  1145.  * In case the format has not been respected, it requires the string reinsertion.
  1146.  * Checks, if necessary, that the time is after a certain time, this is because
  1147.  * the exit time can not be earlier than entry time. */
  1148. void get_valid_time(char *when,
  1149.                     char *bigger_then)
  1150. {
  1151.     struct tm tm_when;
  1152.     int       is_valid = 0;
  1153.     char      *end;
  1154.     do
  1155.     {
  1156.         scanf("%s",
  1157.               when);
  1158.         end = strptime(when,
  1159.                        "%H:%M:%S",
  1160.                        &tm_when);
  1161.         if (end == NULL || *end != '\0')
  1162.         {
  1163.             clear_buffer();
  1164.             printf("Time must be expressed as hh:mm:ss format. Please re-insert it: \n");
  1165.         }
  1166.         else
  1167.         {
  1168.             /* Check that the time is after a certain time, this is because
  1169.             * the exit time can not be earlier than entry time. */
  1170.             if (strlen(bigger_then) > 0)
  1171.             {
  1172.                 if (get_prod_process_time(bigger_then,
  1173.                                           when) >= 0)
  1174.                 {
  1175.                     is_valid = 1;
  1176.                 }
  1177.                 else
  1178.                 {
  1179.                     clear_buffer();
  1180.                     printf("Time bust be bigger then %s. Please re-insert it: \n",
  1181.                            bigger_then);
  1182.                 }
  1183.             }
  1184.             else
  1185.             {
  1186.                 is_valid = 1;
  1187.             }
  1188.         }
  1189.     }
  1190.     while (!is_valid);
  1191. }
  1192.  
  1193. /* This function calculates and returns the processing time in seconds,
  1194.  * obtained from the entry time and the exit time, both passed as arguments. */
  1195. double get_prod_process_time(char *time_entry,
  1196.                              char *time_exit)
  1197. {
  1198.     double    diff_t;
  1199.     struct tm tm_entry, tm_exit, *tm_today;
  1200.     time_t    t_entry, t_exit, rawtime;
  1201.    
  1202.     strptime(time_entry,
  1203.              "%H:%M:%S",
  1204.              &tm_entry);
  1205.     strptime(time_exit,
  1206.              "%H:%M:%S",
  1207.              &tm_exit);
  1208.    
  1209.     time(&rawtime);
  1210.     tm_today = localtime(&rawtime);
  1211.    
  1212.     /* Set on entry time and exit time, day, month and current year, in order to make a correct evaluation. */
  1213.     tm_entry.tm_mday = tm_exit.tm_mday = tm_today->tm_mday;
  1214.     tm_entry.tm_mon  = tm_exit.tm_mon  = tm_today->tm_mon;
  1215.     tm_entry.tm_year = tm_exit.tm_year = tm_today->tm_year;
  1216.    
  1217.     /* Convert the entry time and the exit time from the struct tm format to the suitable type
  1218.      * for storing the calendar format (time_t) in order to calculate the process time. */
  1219.     t_entry = mktime(&tm_entry);
  1220.     t_exit  = mktime(&tm_exit);
  1221.    
  1222.     /* Calculate de time difference in seconds between time exit and time entry. */
  1223.     diff_t = difftime(t_exit,
  1224.                       t_entry);
  1225.    
  1226.     return (diff_t);
  1227. }
  1228.  
  1229.  
  1230. /* General functions */
  1231.  
  1232. /* The function acquires the root and print its data in a formatted way */
  1233. void print_data(struct node *root)
  1234. {
  1235.     printf("\n-------------------------------------------------------------------------------\n");
  1236.     printf("%-15s%-20s%-15s%-20s%-20s\n",
  1237.            "Product id",
  1238.            "Name",
  1239.            "Piece id",
  1240.            "Time entry",
  1241.            "Time exit");
  1242.     printf("-------------------------------------------------------------------------------\n");
  1243.     print_tree(root);
  1244.     printf("-------------------------------------------------------------------------------\n");
  1245. }
  1246.  
  1247. /* Clear buffer function to avoid scanf errors */
  1248. void clear_buffer()
  1249. {
  1250.     char c;
  1251.     while ((c = getchar()) != '\n' && c != EOF);
  1252. }
  1253.  
  1254. int get_valid_int(char *field_name)
  1255. {
  1256.     int  is_valid = 0;
  1257.     int  value;
  1258.     char term;
  1259.     while (!is_valid)
  1260.     {
  1261.         if (scanf("%d%c",
  1262.                   &value,
  1263.                   &term) != 2 || term != '\n')
  1264.         {
  1265.             clear_buffer();
  1266.             printf("%s must be of type integer, try again: ",
  1267.                    field_name);
  1268.         }
  1269.         else
  1270.         {
  1271.             is_valid = 1;
  1272.         }
  1273.     }
  1274.    
  1275.     return value;
  1276. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement