cperryoh

Untitled

Apr 29th, 2022
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 10.05 KB | None | 0 0
  1. /*
  2.  * CSSE 132
  3.  * Rose-Hulman Institute of Technology
  4.  * Computer Science and Software Engineering
  5.  *
  6.  * data.c - Source file with your solutions to the lab.  The
  7.  *          main functionality for this lab should be implemented
  8.  *          here.  This file is used for running the lab's program
  9.  *          and also for running the unit tests.
  10.  *
  11.  *          This is a file you need to hand in!
  12.  *
  13.  * This file contains code used by labs in the CSSE 132 class.
  14.  * When you edit this file for class, be sure to put your name(s) here!
  15.  *
  16.  * Edited by
  17.  * NAMES: Cole Perry
  18.  *
  19.  */
  20.  
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24.  
  25. #include "data.h"
  26.  
  27. // This is the size of our "database" array: it has this many slots and can't
  28. // grow any larger.
  29. const unsigned int DB_MAX_SIZE = 128;
  30.  
  31. /**
  32.  * This formats and prints out a db_entry nicely.
  33.  * We're providing this for you so the output is uniform.
  34.  *
  35.  * @param fd: the file descriptor where the output goes (can be stdout)
  36.  * @param entry: the db_entry struct to print
  37.  */
  38. void dbe_print(struct db_entry *entry, FILE *fileOutput)
  39. {
  40.   //TODO: Modify this function to have an additional FILE* parameter.
  41.   // This way you can print an entry to the screen with:
  42.   //
  43.   //   dbe_print(entry, stdout)
  44.   //
  45.   // or you can print an entry to a file with:
  46.   //
  47.   //   FILE* fd = fopen("myfile.txt", "w");
  48.   //   dbe_print(entry, fd);
  49.   //   fclose(fd);
  50.  
  51.   fprintf(fileOutput, "%s => %s\n", entry->name, entry->value);
  52. }
  53.  
  54. /**
  55.  * Allocates space for a db_entry's members and copies the strings into the
  56.  * newly allocated memory.  If you need space for a string, this is where you
  57.  * allocate it.  This function "constructs" the structure and fills it up.
  58.  *
  59.  * dbe_alloc("me", "val") must allocate contiguous space for two string
  60.  * pointers.  Once that's allocated, it needs to create the space for each
  61.  * string and point the structure's values to the strings.  This example
  62.  * creates a structure in memory that looks like this:
  63.  *
  64.  * db_entry* -> {
  65.  *                char* name: -------> ['m', 'e', '\0']
  66.  *                char* value: ------> ['v', 'a', 'l', '\0']
  67.  *              }
  68.  * The structure itself only needs space for the two pointers, but to figure
  69.  * out how to initialize the pointers, you need to make space for the strings
  70.  * first.
  71.  *
  72.  * @return: a pointer to where the allocated
  73.  */
  74. struct db_entry *
  75. dbe_alloc(const char *name, const char *value)
  76. {
  77.   struct db_entry *r = malloc(sizeof(struct db_entry));
  78.  
  79.   r->name = malloc(sizeof(char) * strlen(name));
  80.   memcpy(r->name, name, strlen(name));
  81.   r->name[strlen(name)] = '\0';
  82.  
  83.   r->value = malloc(sizeof(char) * strlen(value));
  84.   memcpy(r->value, value, strlen(value));
  85.   r->value[strlen(value)] = '\0';
  86.  
  87.   return r;
  88. }
  89.  
  90. /**
  91.  * Releases the memory held by the a db_entry struct.
  92.  * Anything that needed to be malloc()'ed when the structure was created must
  93.  * be free()'ed here.
  94.  *
  95.  * @param entry: a pointer to the structure to free.
  96.  */
  97. void dbe_free(struct db_entry *entry)
  98. {
  99.   free(entry->name);
  100.   free(entry->value);
  101.   free(entry);
  102. }
  103.  
  104. /**
  105.  * Returns the number of non-null entries in the database.
  106.  * For example, given this database:
  107.  *   db = [("A" => "aval"), ("C" => "cval"), 0, 0]
  108.  * db_count_entries(db) returns 2.
  109.  *
  110.  * @param database: a pointer to the database structure
  111.  * @return: the entry count
  112.  */
  113. int db_count_entries(struct db_entry **database)
  114. {
  115.   int i = 0;
  116.   while (i < DB_MAX_SIZE && database[i] != 0)
  117.   {
  118.     i++;
  119.   }
  120.   return i;
  121. }
  122.  
  123. /**
  124.  * Removes the entry at index "index" and shifts the trailing items down.
  125.  * For example, if a database looks like this:
  126.  *   db = [("A" => "aval"), ("B" => "bval"), ("C" => "cval"), 0]
  127.  * when db_remove(db, 1) completes, db will look like this:
  128.  *   db = [("A" => "aval"), ("C" => "cval"), 0, 0]
  129.  *
  130.  * @param database: a pointer to the database structure
  131.  * @param index: the index of the item to remove.
  132.  */
  133. void db_remove(struct db_entry **database, int index)
  134. {
  135.   int i;
  136.  
  137.   if (database[index] == NULL)
  138.   {
  139.     return;
  140.   }
  141.  
  142.   // wipe it
  143.   dbe_free(database[index]);
  144.   database[index] = NULL;
  145.   // shift trailing items left
  146.   for (i = index; database[i + 1] != NULL; i++)
  147.   {
  148.     database[i] = database[i + 1];
  149.   }
  150.   database[i] = NULL;
  151. }
  152.  
  153. /**
  154.  * This looks for "target" in the database and returns the index if found.
  155.  *
  156.  * For example, db_find_one(db, "bob", 0) will search db for any entries with
  157.  * the name starting with "bob", beginning with the first (0th) index.
  158.  *
  159.  * @param database: a pointer to the database structure
  160.  * @param target: a string to look for in the database's names
  161.  * @param initialIndex: a starting index in case you want to search part
  162.  *           of the database
  163.  * @returns the index of the first matching entry or -1 if it wasn't found.
  164.  */
  165. int db_find_one(struct db_entry **database,
  166.                 const char *target,
  167.                 int initialIndex)
  168. {
  169.   int i;
  170.   for (i = initialIndex; database[i] != 0; i++)
  171.   {
  172.     if (strncmp(target, database[i]->name, strlen(target)) == 0)
  173.     {
  174.       return i;
  175.     }
  176.   }
  177.   return -1;
  178. }
  179.  
  180. /**
  181.  * This allocates some memory for a new entry and adds a pointer to it to the
  182.  * end of the database.  
  183.  *
  184.  * @param db: a pointer to the database structure
  185.  * @param name: a string for the name of the entry
  186.  * @param value: a string for the entry's contents
  187.  */
  188. void do_add_entry(struct db_entry **db, const char *name, const char *value)
  189. {
  190.   unsigned int size = 0;
  191.   // find the first null slot and place a new db_entry
  192.   while (size < DB_MAX_SIZE && db[size] != 0)
  193.   {
  194.     size++;
  195.   }
  196.   db[size] = dbe_alloc(name, value);
  197. }
  198.  
  199. /**
  200.  * Prints out all the entries in the database.
  201.  *
  202.  * @param db: a pointer to the database structure
  203.  */
  204. void do_list_database(struct db_entry **db)
  205. {
  206.   int i = 0;
  207.   for (i = 0; i < DB_MAX_SIZE && db[i] != NULL; i++)
  208.   {
  209.     dbe_print(db[i], stdout);
  210.   }
  211. }
  212.  
  213. /**
  214.  * Complete this function:
  215.  * When do_remove_first_match is called, remove the first entry in the database
  216.  * with a name that starts with the value of target.  If no entries start with
  217.  * the string contained in the target parameter, nothing is removed.
  218.  *
  219.  * @param db: a pointer to the database structure
  220.  * @param target: a name of an entry to remove
  221.  * @return: 1 if something was removed, 0 if not.
  222.  */
  223. int do_remove_first_match(struct db_entry **db, const char *target)
  224. {
  225.   int i = -1;
  226.  
  227.   i = db_find_one(db, target, 0);
  228.   if (i < 0)
  229.   {
  230.     return 0;
  231.   }
  232.  
  233.   db_remove(db, i);
  234.   return 1;
  235. }
  236.  
  237. /**
  238.  * Finds and prints all the database entries that start with the given target.
  239.  *
  240.  * This uses dbe_print() to display the matches.
  241.  *
  242.  * For example, output when looking for 'name1' may look like:
  243.  *   name1 => value1
  244.  *   name1 => value2
  245.  *   name1longer => valuelonger
  246.  *
  247.  * @param db: a pointer to the database structure
  248.  * @param target: a string to match in names of entries to find
  249.  */
  250. void do_find_all_matches(struct db_entry **db, const char *target)
  251. {
  252.   //TODO: implement this function.
  253.   // You may want to use db_find_one to reduce code duplication.
  254.   int index = 0;
  255.   do
  256.   {
  257.     index = db_find_one(db, target, index+1);
  258.     printf("%d",index);
  259.     if (index != -1)
  260.     {
  261.       dbe_print(db[index], stdout);
  262.     }
  263.   } while (index != -1);
  264. }
  265.  
  266. /**
  267.  * Exports the database to specified file.  Will create the file if it doesn't
  268.  * exist and replace any contents of the file.
  269.  *
  270.  * @param db: a pointer to the database structure
  271.  * @param filename: a string path to the file
  272.  */
  273. void do_export_db(struct db_entry **db, const char *filename)
  274. {
  275.   //TODO: implement this function.
  276.   // * open the file
  277.   // * write each db entry into it (you can use dbe_print here)
  278.   // * close the file.
  279.   FILE* fileOut = fopen(filename, "w+");
  280.   char buf[128];
  281.   int size = db_count_entries(db);
  282.   for(int i = 0; i < size; i++){
  283.     dbe_print(db[i],fileOut);
  284.   }
  285.   fclose(fileOut);
  286. }
  287.  
  288. /**
  289.  * Reads the database from specified file.  Appends each entry in the file to
  290.  * the database (may cause duplicates).
  291.  *
  292.  * @param db: a pointer to the database structure
  293.  * @param filename: a string path to the file
  294.  * @return the number of entries imported
  295.  */
  296. int do_import_db(struct db_entry **db, const char *filename)
  297. {
  298.   //TODO: implement this function.
  299.   // You will probably want a couple of string buffers
  300.   // to store the name and value read.
  301.   //
  302.   // Hint: you can use fscanf to read from a file, much like fprintf writes to
  303.   // a file.
  304.   // A good format string for fscanf is:
  305.   //     "%128[^ ] => %128[^\n]\n"
  306.   // This format string reads up to 128 characters before a ' ' into one buffer
  307.   // and then up to 128 characters after " => " and before the newline into
  308.   // another.
  309.   //
  310.   // Example use (you need to figure out what "file", "buf", and "buf2" are:
  311.   //    fscanf(file, "%128[^ ] => %128[^\n]\n", buf, buf2);
  312.   //
  313.   // Watch out for extra spaces in the strings you extract from the file!
  314.   //
  315.   // Hint 2: EOF is a constant value that is returned by fscanf when there's no
  316.   // more data to read.  You can also use feof() to check if you are at the end
  317.   // of a file (see the man page).
  318.   //
  319.   // Don't forget to close the file that you open!
  320.   FILE* file = fopen(filename,"r");
  321.   char buf[512];
  322.   char buf2[512];
  323.   while(!feof(file)){
  324.     fscanf(file,"%512[^ ] => %512[^\n]\n", buf, buf2);
  325.     do_add_entry(db,buf,buf2);
  326.   }
  327.   fclose(file);
  328. }
  329.  
  330. /**
  331.  * Helper function for reading a line of input into dest.
  332.  *
  333.  * @param dest: the character buffer (array) where the line should be stored.
  334.  * @param maxlen: the maximum capacity of the buffer.
  335.  * @param fd: the file to read (or stdin)
  336.  * @returns the length of the line read in (minus the newline character).
  337.  */
  338. int getALine(char *dest, int maxlen, FILE *fd)
  339. {
  340.   //TODO: implement this.
  341.   // Use fgets to read some data into dest from fd.
  342.   // Before returning, you should replace newline character with a
  343.   // null character
  344.   fgets(dest,maxlen,fd);
  345.   dest[strnlen(dest,maxlen)-1]='\0';
  346.   return strnlen(dest,maxlen);
  347. }
  348.  
Add Comment
Please, Sign In to add comment