” 辅导CSC 230设计编程、 写作c/c++语言程序CSC 230 Project 4Movie Watch List ManagerFor this project, you get to write a program that will help you manage a list of movies that you would like to watch. It willmaintain a database of available movies, read in at program start-up. By entering commands for the program, the user can viewthe entire movie database, or just the movies from a particular range of years or those with a title containing a given string. Theuser can choose movies to add to their watch list and later remove them if they change their mind.The sample execution below shows how you can run the program. The bold text is input typed by the user. Here, were telling itto read a movie database from the input file, list-d.txt. We ask it to output the entire database (11 movies in this case), andthen we ask it to list just the movies with a year between 1990 and 1999. Then we ask it to display the watch list (which isempty), so we add a few Movies to our watch list and display the list again. Finally, we remove one movie from the list, takeanother look at the list, and enter the quit command to terminate the program.$ ./movies list-d.txtcmd databasedatabaseID Title Year Len4511 Aladdin 1992 904772 Alice in Wonderland 1951 7518145 Cinderella 1950 7461360 Mulan 1998 8870281 Pinocchio 1940 8870767 Pocahontas 1995 8182766 Snow White and the Seven Dwarfs 1937 8399053 The Lion King 1994 88111278 Toy Story 1995 81111279 Toy Story 2 1999 92111280 Toy Story 3 2010 103cmd year 1990 1999year 1990 1999ID Title Year Len4511 Aladdin 1992 9099053 The Lion King 1994 8870767 Pocahontas 1995 81111278 Toy Story 1995 8161360 Mulan 1998 88111279 Toy Story 2 1999 92cmd listlistList is emptycmd add 99053add 99053cmd add 61360add 61360cmd add 111278Add 111278cmd listlistID Title Year Len99053 The Lion King 1994 8861360 Mulan 1998 88111278 Toy Story 1995 81cmd remove 61360remove 61360cmd listlistID Title Year Len99053 The Lion King 1994 88111278 Toy Story 1995 81cmd quitquitAs with recent projects, youll be developing this one using git for revision control. You should be able to just unpack the starterinto the p4 directory of your cloned repo to get started. See the Getting Started section for instructions.This project supports a number of our course objectives. See the Learning Outcomes section for a list.The project uses a list of movies based on the title.basics.tsv.gz file previously retrieved from the IMDb (Internet MovieDatabase) website.Rules for Project 4You get to complete this project individually. If youre unsure whats permitted, you can have a look at the academic integrityguidelines in the course syllabus.In the design section, youll see some instructions for how your implementation is expected to work. Be sure you follow theserules. Its not enough to just turn in a working program; your program has to follow the design constraints weve asked you tofollow. For this assignment, were putting some constraints on the functions youll need to define, the data structures youll use2021/3/23 CSC230 Project 4 httpss://www.csc2.ncsu.edu/courses/csc230/proj/p4/p4.html 2/12and how youre going to organize your code into components. Still, you will have lots of opportunities to design parts of yoursolution and to create additional functions to simplify your implementation.RequirementsThis section says what your program is supposed to be able to do, and what it should do when something goes wrong.Program ExecutionThe movies program expects one or more filenames on the command line. Each of these files should contain a list of movies thatthe program can read into its database at startup. If the program is run with invalid command-line arguments (e.g., no filenamesgiven on the Command line), it should print the following usage message to standard error and exit with a status of 1.usage: movies movie-list*If the program cant open one of the given files for reading, it should print the following message to standard error and exit witha status of 1. Here, filename is the name of the file given on the command line. The program should report the first filename onthe command line that it cant successfully open (i.e., if there are multiple filenames on the command line that cant be opened,it just needs to report this error for the first one that cant be opened).Cant open file: filenameMovie List FormatAt program start-up, the movies program reads in a database of movies. On the command line, it is given one or more filenamesfor files containing movie lists, stored in a particular format. Each line of a movie list file describes one movie. A moviedescription consists of five fields, with tab characters (ASCII 0x09) separating the fields. The first field is an integer ID unique tothe given movie. The next field is a title for the movie (a string). The next field is a integer year of when the movie was released.The next field is an integer length of the movie in minutes and the last field is a string listing various genres for the movie. Thelist of genres is a comma-separated list of strings. None of the fields will contain a tab character, and none of them will be empty.Format of a line of a Movie ListYour program will only use the genre field if youre doing the extra credit part of the assignment. Otherwise, your program canjust skip over this field as it reads in a movie list. The possible genres are Action, Adventure, Animation, Biography, Comedy,Crime, Documentary, Drama, Family, Fantasy, History, Horror, Musical, Mystery, Romance, Sci-Fi, Sport, Thriller, War, andWestern.Some of the title fields are fairly long, but you will only need to store the first 38 characters of the title. This is described in theMovie Listing section below.The program should process the movie list files in the same order they are given on the command line. Within each movie list, itshould process movies in order from the first line to the last line of the file. The order for processing these files matters for errorreporting. If there is something wrong with a movie list, the program should report the first error it encounters.A movie list file can contain any number of movie descriptions, one per line. If the format of the movie list is invalid (e.g., if a lineis missing one of the expected fields or if one of the numeric fields cant be parsed as a number), then it should print thefollowing message to standard error and exit with a status of 1. Here, filename is the name of the file containing the bad moviedescription.Invalid movie list: filenameEvery movie should have a unique numeric ID. If the program encounters more than one movie with the same ID (even if otherfields like the title or year are different), it should print the following message to standard error and exit with a status of 1. Here,ID is the movie ID that occurred more than once. The program should detect duplicate IDs, whether they occur within the samemovie list file or across two different Movie lists.Duplicate movie id: IDWatch ListAs the user interacts with the movies program, they can select movies from the database to add to their watch list, a subset ofmovies the user plans to watch. The database is the set of all movies available, and the watch list is the subset of the databasethat the user has selected.Its possible for the watch list to be empty (its empty when the program starts up). Its managed like a set, so it cant containmore than one of the same move.Movie List OutputA few user commands are used to list movies, either from the database or from the watch list. The output format for thesereports is mostly the same. It consists of a header describing each of the four fields (like the example shown below). After theheader, the report lists one movie per line. Each movie is reported as a movie ID in a 6-character field, a movie title in a 38character field, a movie year in a 4 character field, and finally a movie length given in a 3 character field. For the year and themovie length, the widths of 4 and 3 are minimum field widths, so its possible to have a year with more than four digits or a2021/3/23 CSC230 Project 4 httpss://www.csc2.ncsu.edu/courses/csc230/proj/p4/p4.html 3/12length with more than Three digits. For cases like these, the columns may not line up properly. Each of these fields is rightalignedand has a single space separating them.ID Title Year Len8466 Avatar 2009 16284694 Star Trek VI: The Undiscovered Country 1991 11084702 Star Wars: Episode IV – A New Hope 1977 12194055 The Englishman Who Went Up a Hill Bu.. 1995 99108082 The Wizard of Oz 1982 78For movie titles that are too long to fit in their field width, you will print as much of the title as you can, and then print twoperiods instead of the last two characters of the field, to indicate that the whole title was too long to fit. You can see this in theThe Englishman Who Went Up a Hill But Came Down a Mountain title above. Here, we print just the first 36 characters of thetitle, then print two periods at the end, making the overall length exactly 38 characters.User CommandsAfter start-up, the movies program reads commands typed in by the user. Each command is given as single line of user input.For each command, the program will prompt the user with the following prompt. Theres a space after the greater-than sign, butyou probably cant see it in this web page.cmdAfter the user enters a command, the program will echo that command back to the user on the next output line. This is mostly tohelp with debugging your programs. If were capturing program output to a file, then things typed by the user dont go to theoutput file (user inputs show up on the terminal, but theyre not part of the programs output). By echoing each command, ouroutput files will include a copy of each command the user typed, making it easier to see what the program was asked to do. So,for example, if the user typed in a command like the following, the program would echo a copy of the command on the next line:cmd year 1990 1999year 1990 1999The user can type any of 7 (or 8) available commands: database, year, title, add, remove, list and quit. There is also agenre command that can be implemented for extra credit. These commands are described below. Each valid command startswith one of the keywords listed above. For some commands, the keyword must be followed by one or more parameters. Theremay be one or more whitespace characters at the start of the command, between the keyword and the parameters, betweenparameters or at the end of the command. Any non-whitespace characters on a line following a valid command (and itsparameters, if any) may be ignored by the program.If the user enters an invalid command, the program should print the following message to standard output (not standard error),ignore the command and prompt the user for another command. Invalid commands would be those that start with somethingother than the 7 (or 8 for extra credit) keywords listed above, or if the commands parameters werent correct.Invalid commandAfter the first prompt, the program should print a blank line before prompting the user for another command. This is shown inthe sample execution at the start of this project description. Its just to provide a little separation between the output forconsecutive commands.The program should terminate when it is given the quit command or when it reaches the end-of-file on standard input. In thecase of the quit command, the program should echo the command back to the user (like all the other commands). In the case ofend-of-file, theres no command to echo, so the program should just terminate.Database commandIf the user enters the database Command, the program should print out all the movies in the entire database in the formatdescribed in the Movie List Output section above. Movies should be sorted by their ID field, least to greatest.If there are no movies in the database (this could happen if the program was given an empty movie list file to read), theprogram should print the following message to standard output and then prompt for another command.No matching moviesYear commandThe year command requires two integer parameters, a low value and a high value. It lists movies from the database with a yearat least as high as the low value and no higher than the high value. Output should be given in the format described in the MovieList Output section above, ordered by year, from low to high. Movies with the same year should be sorted by ID.For example, the user could enter the following year command, with the following response from the program. Notice that thetwo movies with a year of 1995 are ordered by ID number.cmd year 1990 1999year 1990 1999ID Title Year Len4511 Aladdin 1992 9099053 The Lion King 1994 8870767 Pocahontas 1995 81111278 Toy Story 1995 8161360 Mulan 1998 88111279 Toy Story 2 1999 922021/3/23 CSC230 Project 4 httpss://www.csc2.ncsu.edu/courses/csc230/proj/p4/p4.html 4/12The year command would be invalid if it was missing a parameter, or one of its parameters couldnt be parsed as an integervalue, or if its first parameter was greater than its second parameter. If the range of years doesnt contain any movies, theprogram should print a line to standard output saying No matching movies, like in the following example:cmd year 1978 1979year 1978 1979No matching moviesTitle commandFor this command, the user can Enter a single-token string. The program will find all movies in the database that contain thatstring as a substring in their title field. It will print out just these movies from the database in the format described in the MovieList Output section above, with movies whose title contains or is equal to the given string listed in order of ID. A movies titlefield matches the given string even if the string is just a substring of a longer word in the movies subject field. For example, ifthe user entered title and, then it could match a movie that had the word and in its title field, or one that had the wordWonderland in its title field. For example,cmd title andtitle andID Title Year Len4772 Alice in Wonderland 1951 7582766 Snow White and the Seven Dwarfs 1937 83If there are no matching movies in the database, the title command should print the No matching movies message to standardoutput, just like the database and year commands.A title command would be invalid if it didnt have a string after the title keyword.Genre commandThe genre command is for extra credit. For this command, the program will need to store the list of genres for each movie (thelast field on each line in a movie list). The user can enter the genre keyword, followed by a single word (a sequence of nonwhitespacecharacters). The program will find all movies in the database that contain that word as a substring in their genrefield. It will print out just these movies from the database in the format described in the Movie List Output section above, withmovies that match the given word listed in order of ID. A movies genre field matches the given word even if the word is just asubstring of a longer word in the movies genre field. For example, if the user entered genre mat, then it could match a moviethat had the word the word Animation in its genre field.If there are no matching movies in the database, the genre command should print the No matching movies message tostandard output, just like the database and year commands.A genre command would be invalid if it didnt have a word after the genre keyword.Add commandThe add command is for adding movies from the database to the watch list. Movies added to the watch list are added at the end,and adding a movie to the watch list doesnt remove it from the database; it just puts that movie on the watch list. The addcommand expects a movie ID as a parameter. So, for example, the following command would add the movie with an ID of 42 tothe watch list.add 42An add command would be invalid if there wasnt an integer after the add keyword. If the integer doesnt match a movie ID fromthe database, the program should print the following to standard output (where ID is the ID the user asked to add).Movie ID is not in the databaseIf the user gives the ID of a movie thats already on the watch list, the program should print the following message to standardoutput (where ID is the ID the user asked to add):Movie ID is already on the watch listRemove commandThe remove command is for Removing movies from the watch list. As a parameter, it expects the ID of the movie to be removed.It removes that movie from the watch list, and the remaining movies stay in the same order. So, for example, the followingcommand would remove the movie with an ID of 42 from the watch list.remove 42If the remove command isnt given a valid integer as a parameter, then it is an invalid command. If the parameter is a validinteger but doesnt match the ID of a movie on the watch list, then it should print the following message to standard output,where ID is the ID of the movie the user asked to remove.Movie ID is not on the watch listList commandThe list command shows the movies on the watch list in the same format described in the Movie List Format section above.Notice that the watch list is ordered based on the order movies were added (not sorted by ID).For example, running the list command might look like the following.cmd listlist2021/3/23 CSC230 Project 4 httpss://www.csc2.ncsu.edu/courses/csc230/proj/p4/p4.html 5/12ID Title Year Len70356 Pirates of the Caribbean: The Curse .. 2003 14359720 Mission: Impossible 1996 11091003 The Bourne Identity 2002 11930675 Ferris Buellers Day Off 1986 103If the watch list is empty, the program should print a line to standard output saying List is empty.So, for example, you might get the following response from a list command:cmd listlistList is emptyQuit command and terminationThe quit command doesnt take any parameters. It should terminate the program. Its entered like the following:cmd quitThe program should also terminate successfully if it reaches the end-of-file on standard input while its trying to read the nextcommand.DesignProgram OrganizationYour implementation will be organized into three components. The input component will help with reading input from the movielist files and from the user. The database component will contain code for implementing movies and the database. The moviescomponent will contain main, code to read in user commands and the implementation for the watch list.Components and Dependency StructureThe input and database components will each have a header file, so other components can use types and functions defined bythese components. The figure above shows the dependency structure of the project. The database component can use codeprovided by input and the main movies component can use code provided by both input and database.Movie and Database RepresentationThis project is a good chance to get some experience using structs, dynamic memory allocation and resizable arrays. Each moviewill be represented by a struct with a field for each of the four values associated with a movie. The title field will be a string, andthe ID, year, and length can be stored as ints. The title field just needs to be able to store a string of up to 38 characters.Although lots of titles are longer than this, the output of the program never reports more than 38 characters for a title, so youwont need to store more than the first 38 characters.2021/3/23 CSC230 Project 4 httpss://www.csc2.ncsu.edu/courses/csc230/proj/p4/p4.html 6/12Movie RepresentationThe database will be represented by its own struct, containing fields to store a resizable array of pointers to movies. Each moviewill be stored in a block of dynamically allocated memory. Inside the Database struct, you will use a resizable array of pointers tomovies to keep up with all the movies in the database. The count and capacity fields are for maintaining the resizable array, forkeeping up with how many movies are in the database and for detecting when you run out of capacity and need to grow thearray. Your resizable array should Start with an initial capacity of 5, and it should double in capacity whenever the array needs tobe enlarged.Database RepresentationExtra Credit Design and ImplementationIf you do the extra credit part of this project, each movie will need to store a string of genre keywords read from the movie listfiles. The genres for a movie may be a long string, so were not going to store it inside the movie struct. Instead, the string willbe stored in another block of dynamically allocated memory, and the movie struct will just keep a pointer to this string. That way,the genre string can be exactly as long as it needs to be to hold whatever genre string is given in the movie list input.Movie Representation with GenresWatch List RepresentationYou will represent the watch list as a resizable array in the top-level movies component. Like the database, this array shouldstart with an initial capacity of 5 and it should double in size whenever it needs to grow.You can represent your watch list however you want to. If you want, you can store it inside a struct, like were doing with theDatabase, or you can just use some global variables inside the movies component to keep up with the watch list. If you dochoose to use some global variables for the watch list, be sure to mark them as static. This will prevent possible name collisionswith symbols defined elsewhere in your program.Expected FunctionsAs part of your implementation, you will define and use the following functions. You can define more if you want to. Just try toput them in a component thats suitable for whatever they do and remember to mark them as static where you can (i.e., if2021/3/23 CSC230 Project 4 httpss://www.csc2.ncsu.edu/courses/csc230/proj/p4/p4.html 7/12theyre not used outside the component where theyre defined).Your input component only needs to have one function.char *readLine( FILE *fp )This function reads a single line of input from the given file and returns it as a string inside a block of dynamically allocatedmemory. You can use this function to read commands from the user and to read movie descriptions from a movie list file.Inside the function, you should implement a resizable array to read in a line of text that could be arbitrarily large. If theresno more input to read, this function should return NULL. Since this function returns a pointer to dynamically allocatedmemory, some other code will be responsible for eventually freeing that memory (to avoid a memory leak).Your database component should have the following 7 (or 8) functions.Database *makeDatabase()This function dynamically allocates storage for the Database, initializes its fields (to store a resizable array) and returns apointer to it.void freeDatabase( Database *dat )This function frees the memory used to store the database, including freeing space for all the movies, freeing the resizablearray of movie pointers and freeing space for the database struct itself.void readDatabase( Database *dat, char const *filename )This function reads all the movies from a movie list file with the given name. It makes an instance of the Movie struct foreach one and stores a pointer to that movie in the resizable arrayvoid listAll( Database *dat )This function lists all the movies in the database, sorted by ID number. The movies component can call this in response tothe user entering the database command.void listYear( Database *dat, int min, int max );This function lists all the movies with a year between the given min and max values (inclusive). Your movies component cancall this when the user enters the year command. In the output, movies should be sorted by year, and by ID if they havethe same year.void listTitle( Database *dat, char const *title )This function lists all the movies where the given title string occurs in the movies title field. In the output, the moviesshould be listed in order by ID. For this function (and the extra credit listGenre() function), you may find the strstr()function useful for finding a short string inside a larger one. We will talk about this function briefly in class, but, if you wantto use it, you may need to do some reading on your own. Youll find it on page 620 of your textbook, or, if youre on a Linuxmachine, you can just type man strstr at the shell prompt to look at the online documentation.void listGenre( Database *dat, char const *genre )You only need this function if youre doing the extra credit. It reports all movies where the given genre string occurs in themovies genres field. In the output, the movies should be listed in order by ID.void listDatabase( Database *dat, bool (*test)( Movie const *movie, void const *data ), void const *data )This is a static function in the database component. It is used by the listAll(), listYear(), listTitle(), and listGenre() functionsto actually report the list of movies in the right format. In addition to a pointer to the database, this function also takes apointer to a function (test) and a pointer to an arbitrary block of data (data) to let the caller tell the function whichparticular movies it should print out. This is described in more detail in the Selecting Movies to Report section below.Your movies component will contain main() and any other functions you need to parse command-line arguments and usercommands.Function VisibilityAny functions that are needed by a Different component should be prototyped (and commented) in the header. Functions thatdont need to be used by a different component should not be prototyped in the header, and should be marked static (giveninternal linkage), so they wont be visible to any other part of the program. This is like making the function an implementationdetail of its component, something we could change if we wanted without affecting other parts of the program.Sorting the DatabaseYoull use the standard library qsort() function to sort movies, either by ID or by year (and ID). Using qsort() will make thesorting easier (and probably more efficient), but you have to help out qsort() by providing a pointer to a comparison function. Wehave some examples of this in the material from lecture 12, in the slides and in the sort.c example program.To use qsort() youll need to think about a few things. As usual, youll need to write your own comparison function, one thattakes two (const) void pointers, but knows that theyre really pointers to two elements of the array inside the Database struct.So, your comparison function will need to cast these void pointers to pointers of the right type before it can start looking at thefields of the Movie objects they point to. Remember that the comparison function gets pointers to two array elements (not copiesof the values in two array elements, pointers to the elements). So, for example, since the array is full of pointers to Moviestructs, your comparison function will get two pointers to pointers to Movie instances. You have to define your comparison so ittakes two void pointer parameters, but, internally, your comparison function will know that these are really pointers to pointersto Movies. After casting the void pointers parameters to these more specific types, you can access the fields of the Movies inorder to compare them.You have to sort the database two different Ways (for the year command vs for the database and title commands), so you willneed to implement two different comparison functions for sorting the movies in the database.2021/3/23 CSC230 Project 4 httpss://www.csc2.ncsu.edu/courses/csc230/proj/p4/p4.html 8/12Parsing User CommandsWere reading user input one line at a time. After we get a string containing a command, we will need to look inside this string tofigure out what command the user typed. The sscanf() function will make it easy to do this. It works much like scanf() orfscanf(), but it parses input from a string instead of from a file. Well cover this function in lecture 18, but you may want to lookat the material for lecture 18 early (it should already be posted) so you can get started on the project earlier.Remember, unlike reading from a file, sscanf() doesnt automaticall resume parsing from where it left off on the last call. Forexample, you couldnt call something like sscanf( str, %d, x ); to read an int then call sscanf( str, %d, y ); againto read the next int. If you gave sscanf() the same string in two successive calls, it would just start parsing at the start of thestring each time. If you want to parse multiple values out of the same string, you can do it all at once, like\r”
添加老师微信回复‘’官网 辅导‘’获取专业老师帮助,或点击联系老师1对1在线指导。