代写COMP 206: Introduction to Software Systems Assignment 4: files and pointers Winter 2024代写留学生Java程序

- 首页 >> C/C++编程

COMP 206: Introduction to Software Systems

Assignment 4: files and pointers

Winter 2024

Before you start, please read the following instructions:

•  Individual assignment

This is an individual assignment.  Collaboration with your peers is permitted (and encouraged!)  provided that no code is shared; discuss the ideas.

•  Use Discord and OH for questions

If you have questions, check if they were answered in the #clarifications or #q-and-a channels on Discord. If there is no answer, post your question on the forum.  Donotpost your code.  If your question cannot be answered without sharing significant amounts of code, please use the TA/Instructors office hours.  Do  not email the TAs and Instructors with assignment questions.  TAs should only be contacted by emails if you have questions about a grade you received.

•  Late submission policy

Late penalty is -10% per day. Maximum of 2 late days are allowed.

•  Must be completed on mimi server

You must use mimi.cs.mcgill.ca to create the solution to this assignment.  An important objective of the course is to make students practice working completely on a remote system. You cannot use your Mac/Win- dows/Linux terminal/command-line prompt  directly without  accessing the  mimi  server.   You  can  access mimi.cs.mcgill.ca from your personal computer using ssh or putty as seen in class and in Lab A. If we find evidence that you have been doing parts of your assignment work elsewhere than the mimi server,  you  might  lose  all  of the  assignment  points.   All of your solutions should be composed of commands that are executable in mimi.cs.mcgill.ca.

•  Must be completed with vim

A goal of the class is to get you to be comfortable in a command-line text editor. This wouldn’t happen just from knowing the vim commands from slides: You become comfortable by using it a lot.  Assignments are a good opportunity for that.

• You must use commands from class

In this assignment, anything in the C standard library is allowed.  However, the emphasis in the assessment is on clarity and readability of the code. Do not do anything unnecessarily generalized, abstract, or complex, when simple, straightforward code suffices.

• Your code must run

Your code must run as-is and nearly instantly. TAs WILL NOT modify your code in any way to make it work.

•  Please read through the entire assignment before you start working on it

You can lose up to points for not following the instructions in addition to the points lost per questions.

1   A CSV-backed database written in C

In this assignment, your task will be to implement a command-line program called  igdb in C for managing a persistent database stored as a CSV file.  This is a simplified example of what C is actually used for in practice: writing fast, low-level data management software. The popular, high-performance, open-source relational database management system PostgreSQL is written in C, for instance.

Learning goals assessed:

1. Write robust system interactions in C.

2.  Create custom data structures and algorithms in C.

3.  Organize code in C for readability.

1.1   Whats in the database?

The database in this assignment is for tracking Instagram accounts. One record in the database stores the following information.

•  Handle, e.g. @spottedmcgill

•  Follower count, e.g.  14900

•  Comment, e.g. a  bit  cringe  tbh

•  Date last modified, e.g.  1710521259

This record would be represented in CSV form as

@spottedmcgill ,14900 ,a  bit  cringe  tbh ,1710521259

To accommodate the CSV file format, the characters  '\0' (null)  '\n' (line feed) and  ',' (comma) are forbidden from appearing in the comment field.

1.2   Representing dates and times

You might have noticed that the “date last modified” above doesn’t look like a date at all...

Representing dates and times robustly can be a challenge in software engineering.  A very common and straight- forward solution is to represent an absolute moment in time in so-called UNIX Epoch format. This is thenumber of secondselapsedsincemidnighton 1 January 1970.  These are also called  (UNIX) timestamps.  This format is independent of timezones, which makes it great for storage in a database.  User-facing applications convert these timestamps into human-readable “local time” strings, accounting for timezomes, when displaying the time to a user.

Your database will store UNIX timestamps, and your application must present these times in human-readable strings in the local timezone.  The C standard library contains functions for working with UNIX timestamps and dates and times in general.

• You will need to #include  <time.h>

•  See man  2  time (get current timestamp)

•  See man  3  localtime (convert timestamp into time structure in current timezone)

•  See man  3  strftime (format time structure into string)

1.3   Representing database records in C

You must define a struct  Record to represent a single line (record) from the CSV file (database).  It must have one member for each of the fields of the record described above.

•  The “handle” and “comment” fields must be character arrays (not pointers) with sizes 32 and 64 respectively.

•  The “follower count” and “date last modified” fields must be of type long  unsigned  int

1.4   Representing the database itself in C

You must define a struct  Database to represent a whole database.  This will be an implementation of dynamic arrays, i.e. arrays that can “grow” during runtime, similar to the ArrayList class in Java or Python’s built-in list.

A dynamic array has three attributes: a pointer to an underlying (fixed-size) array, an integer called the capacity, and an integer called the size.  The capacity is the length of the underlying array, and the size is the count of elements actually stored inside that array.

When we want to add an item to the end of a dynamic array, we have to check if there’s space left in the underlying array by comparing the size and the capacity. If the size is less than the capacity, then we can treat the size as the index at which to write the new item, then increment the size. Else, when the size has reached the capacity, a new underlying array with double thecapacity is allocated, the elements from the old array are copied to the new array, and the old array’s memory is freed, before proceeding as before.

You must implement the following functions for handling the dynamic array.

typedef   struct  Database  {  /*  fill   this   in  */  }  Database ;

Database  db _ create ();

//   ^  The   database  must   have   initial   size   0  and   capacity  4 .

void  db _ append ( Database  *  db ,  Record   const  *  item );

//   ^  Copies   the   record  pointed   to   by   item   to   the   end   of   the   database .

//  This   is   where  you  need   to   implement   the   resizing   logic   described   above .

Record  *  db _ index ( Database  *  db ,  int   index );

//   ^  Returns  a  pointer   to   the   item  in   the   database   at   the  given   index . //  You  need   to   check   the   bounds   of   the   index .

Record  *  db _ lookup ( Database  *  db ,   char  const  *  handle );

//   ^  Returns  a  pointer   to   the  first   item  in   the   database  whose   handle //  field   equals   the  given  value .

void  db _free ( Database  *  db );

//   ^  Releases   the  memory   held   by   the   underlying   array .

//  After  calling   this ,   the   database   can  no   longer  be  used .

To implement these functions, you will need to use some of the standard library functions for memory management: check out malloc, calloc, realloc, and free.

As usual, you can check the documentation for these with, e.g. man  3  malloc.

1.5   Reading and writing CSV files

When the database application starts, it will load the file database.csv into memory, populating a Database object. When the application runs, the user will be able to command it to write the database. You will implement the following functions that accomplish reading and writing the whole database.

void  db _ load _ csv ( Database  *  db ,  char  const  *  path );

//   ^  Appends   the  records   read  from   the  file   at   `path `

//  into   the   already   initialized   database   `db ` .

//   (The  given   database   does   not   have   to   be   empty .)

void  db _write _ csv ( Database  *  db ,  char  const  *  path );

//  ^  Overwrites   the  file   located  at   `path `  with   the

//  contents   of   the   database ,   represented   in  CSV  format .

Of course, reading the database can be decomposed into two subproblems:  parsing a single line of the CSV file into a Record structure versus looping over all the lines in the file to populate the whole database.  Your code must reflect this separation of concerns by implementing and using the following function.

Record  parse _record ( char  const  *  line );

//   ^  Parses   a  single   line   of  CSV  data   into   one  Record

You must use the following standard library functions to implement the functions in this section.

•  fopen to open files for reading or writing. You must call fclose on these when you finish reading or writing.

• getline reads a line from a stream. You must be careful to properly free any buffers that this function might allocate for you.

•  fprintf writes formatted data to a given stream.

•  strtok is used to break up a string according to a delimiter, such as  ','.

As always, check the documentation in the man pages, e.g. man  3  getline.

1.6   User interactions with the database

The user manipulates the data in the database via interactive prompt. The below example session illustrates how this should work. Each line beginning with > is a prompt, and my input is given after it.

jerrin@teach -node -04:~ $   ./ igdb

Loaded  5  records .

>  list

HANDLE                          |   FOLLOWERS    |   LAST   MODIFIED           |   COMMENT

----------------|-----------|------------------| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

@spottedmcgill     |   14900          |  2024 -03 -15   17:03   |  a  bit  cringe  tbh

@foo                            |  420               |  2024 -03 -13   13:37   |  foo   is  foo

@bar                         |  8008135       |   2024 -03 -14  20:03   |  go  to  bar

@foobar                   |  8008555       |  2024 -03 -15   17:01   |  foo  +  bar  =  foobar

@quux                       |   1234567       |   2024 -03 -16   16:06   |  how   to  pronounce   quux?

>  add  @zzzz  98765

Comment >  sleeping  in  is  great  zzzz

>  list

HANDLE                          |   FOLLOWERS    |   LAST   MODIFIED           |   COMMENT

----------------|-----------|------------------| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

@spottedmcgill     |   14900          |  2024 -03 -15   17:03   |  a  bit  cringe  tbh

@foo                            |  420               |  2024 -03 -13   13:37   |  foo   is  foo

@bar                         |  8008135       |   2024 -03 -14  20:03   |  go  to  bar

@foobar                   |  8008555       |  2024 -03 -15   17:01   |  foo  +  bar  =  foobar

@quux                       |   1234567       |   2024 -03 -15   17:03   |  how   to  pronounce   quux?

@zzzz                          |  98765           |  2024 -03 -15   17:08   |  sleeping   in  is  great  zzzz

>  update  @bar  0

Comment >   !!! account  deleted !!!

>  add

Error :  usage :   add  HANDLE  FOLLOWERS

>  add  @loo ooo ooo ooo ooo ooo ooo ooo ooo ong . name   12345

Error :  handle  too  long .

>  add  @short . name   12345

Comment >  ummm ,  this   is  a  comment

Error :  comment   cannot   contain   commas .

>  add  @short . name  lmao

Error :  follower   count  must  be  an  integer

>  list

HANDLE                          |   FOLLOWERS    |   LAST   MODIFIED           |   COMMENT

----------------|-----------|------------------| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

@spottedmcgill

|   14900

|  2024 -03 -15

17:03   |  a  bit  cringe  tbh

@foo

|  420

|  2024 -03 -13

13:37   |  foo  is  foo

@bar

|  0

|  2024 -03 -15

17:09   |   !!! account  deleted !!!

@foobar

|  8008555

|  2024 -03 -15

17:01   |  foo  +  bar  =  foobar

@quux                          |   1234567

|  2024 -03 -15   17:03   |  how  to  pronounce  quux?

@zzzz                         |   98765

|  2024 -03 -15   17:08   |  sleeping  in  is  great  zzzz

>  update  @wow   12345

 

Error :  no  entry  with  handle >  add  @spottedmcgill   12345

@wow

Error :  handle  @spottedmcgill

>  exit

already  exists .

Error :  you  did  not  save  your

>  save

changes .  Use   `exit  fr `  to  force  exiting  anyway .

Wrote  6  records .

 

>  exit

 

jerrin@teach -node -04:~ $

 

Here is a detailed description of the commands that your interactive mode must support.

•  list – print out the whole database formatted as a table.  For the widths of the columns, you can choose a fixed width, but make sure that the output always looks like a decent table.  For instance, if you choose a fixed width of 20 characters for the handle, but the handle is 25 characters long, you should truncate the remaining extra characters from the handle to make it fit in the column. The same applies to the comment. This can be accomplished using the “width” and “precision” modifiers for the %s directive of printf.

•  add  HANDLE  FOLLOWERS – adds a new entry to the end of the database.  That handle must not already exist in the database. A follow-up prompt is generated to ask the user for the value of the comment field.

• update  HANDLE  FOLLOWERS – updates an existing entry for the given handle.  An entry for that handle must be present. A follow-up prompt is generated to ask the user for the value of the comment field.

•  save – writes the database out to the file database.csv

•  exit – quits the program, but warns the user about unsaved changes if any.

As in the previous assignment, your implementation must be robust in the face of userinput.  Therefore, for things such as integers written by the user in prompts, you will need to use strtol as in the previous assignment to ensure that valid input is given.

However, you may assume that the CSV file is well-formed, so you do not need to validate, for instance, that the value stored in the follower count column contains only digits.

2   What to hand in

This assignment comes with starter code.

You should modify the files database.c, database.h, and igdb.c from the starter code, providing the implemen- tations for all the functions described above.

The starter code contains a Makefile, which you can run via the command make.  This will compile each C file separately and then link them together into an executable igdb.

On MyCourses, you must submit a zip file containing database.c, database.h, igdb.c, and the Makefile.





站长地图