C++代写:CA246 I/O Probleams

Introduction

这次作业必须使用C++的I/O库,并且用C++的方式来处理异常,属于比较偏门的作业。

Requirement

Note: You must use the C++ I/O streaming and memory management facilities on this assignment. Marmoset will be programmed to reject submissions that use C-style I/O or memory management.
Note: For this assignment, you must deal with all I/O problems by handling exceptions. Your programs must begin with cin.exceptions(ios::eofbit|ios::failbit);. Moreover, you must issue this same call for any stream objects (file stream or string stream) that you create (for string streams, you may wish to turn on exceptions for ios::failbit only, as turning on exceptions for ios::eofbit will cause an exception on a successful read of the last word from a stringstream, if there is no whitespace following it).
Note: For this assignment, you are not allowed to use the array (i.e., []) forms of new and delete. Further, the CXXFLAGS variable in your Makefile must include the flag -Werror=vla. Note: Each question on this assignment asks you to write a C++ program, and the programs you write on this assignment each span multiple files. For this reason, we strongly recommend that you develop your solution for each question in a separate directory. Just remember that, for each question, you should be in that directory when you create your zip file, so that your zip file does not contain any extra directory structure.
Note: Problem 3 asks you to work with XWindows graphics. Well before starting that question, make sure you are able to use graphical applications from your Unix session. If you are using Linux you should be fine (if making an ssh connection to a campus machine, be sure to pass the -Y option).
If you are using Windows and putty, you should download and run an X server such as XMing, and be sure that putty is configured to forward X connections. Alert course staff immediately if you are unable to set up your X connection (e.g. if you can’t run xeyes).
Also (if working on your own machine) make sure you have the necessary libraries to compile graphics. Try executing the following:

g++ window.cc graphicsdemo.cc -o graphicsdemo -lX11

Problem 1

The purpose of this problem is to get you used to handling I/O exceptions. Write a program that consumes the names of several files on the command line, and computes the sum of all integers found in the files (we define an integer to be any sequence of characters for which reading from a stream into an integer variable succeeds). However, some of the files whose names were given to the program may not exists, and not everything in these files is a number. When the program is finished, it must print out a list of all files that did not exist, the total of all numbers found, and the total number of words in all files that did not denote numbers.
For example, if file a contains 1 2 3 4 5, file b contains 1 b 3 d 5 and files c and d do not exist, then ./a4q1 a b c d should produce the following output:

Non-existent files: c d
Total of numbers: 24
Total non-numbers: 2

The number of command-line arguments could be arbitrarily long; do not assume an artificial maximum.
If reading a number fails, consume a word (i.e., up to the next whitespace) and proceed from there. For example, if a contains 2.5, then ./a4q1 a should produce Non-existent files:

Total of all numbers: 2
Total number of non-numbers: 1
To submit: Submit your solution. You must include a Makefile, such that issuing the

command make will build your program. The executable should be called a4q1.

Problem 2

In this problem, you will write a program to read and evaluate arithmetic expressions. There are three kinds of expressions:

  • lone integers
  • a unary operation (NEG or ABS, denoting negation and absolute value) applied to an expression
  • a binary operation (+, -, *, or /) applied to two expressions

Expressions will be entered in reverse Polish notation (RPN), also known as postfix notation, in which the operator is written after its operands. For example, the input

12 34 7 + * NEG

denotes the expression - (12 * (34 + 7)). Your program must read in an expression, print its value in conventional infix notation, and then print its value. For example (output in italics):

1 2 + 3 4 - * ABS NEG - | ((1 + 2) * (3 - 4))|
= -3

To solve this question, you will define a base class Expression, and a derived class for each of the the three kinds of expressions, as outlined above. Your base class should provide virtual methods prettyprint and evaluate that carry out the required tasks.
To read an expression in RPN, you will need a stack. Use cin with operator >> to read the input one word at a time. If the word is a number, create a corresponding expression object, and push a pointer to the object onto the stack. If the word is an operator, pop one or two items from the stack (according to whether the operator is unary or binary), convert to the corresponding object and push back onto the stack. When the input is exhausted, the stack will contain a pointer to a single object that encapsulates the entire expression.
Once you have read in the expression, print it out in infix notation with full parenthesization, as illustrated above. Then evaluate the expression and print the result.
Note: Your program should be well documented and employ proper programming style. It should not leak memory. Markers will be checking for these things.
Note: The design that we are imposing on you for this question is an example of the Interpreter pattern (this is just FYI; you don’t need to look it up, and doing so will not necessarily help you).
To Submit: A UML diagram (in PDF format q2UML.pdf) for this program. There are links to UML tools on the course website. Do not handwrite your diagram. Your UML diagram will be graded on the basis of being well-formed, and on the degree to which it reflects a correct design. Also, submit the C++ code for your solution. You must include a Makefile, such that issuing the command make will build your program. The executable should be called a4q2.

Problem 3

In this problem, you will use C++ classes to implement the game of Lights Out. An instance of Lights Out consists of an n × n-grid of cells, each of which can be either on or off. When the game begins, we specify an initial configuration of on and off cells. Lights Out is a one-player game. Once the cells are configured, the player chooses a cell and turns it on if it is off, and off if it is on. In response the four neighbouring cells (to the north, south, east, and west) all switch configurations between off and on as well. The object of the game is to get all of the cells turned off.
To implement the game, you will use the following classes:

  • class Observer — abstract base class for observers (see provided observer.h; the file also contains an enumeration of possible subscription types);
  • class Cell — implements a single cell in the grid (see provided cell.h);
  • class Grid — implements a two-dimensional grid of cells (see provided grid.h);
  • class TextDisplay — keeps track of the character grid to be displayed on the screen (see provided textdisplay.h).

Note: you are not allowed to change the public interface of these classes (i.e., you may not add public fields or methods), but you may add private fields or methods if you want.
Your solution to this problem must employ the Observer pattern. Each cell of the grid is an observer of all of its neighbours (that means that class Cell is its own observer). Thus, when the grid calls Cell::notifyNeighbours on a given cell, that cell must then call the notify method on each of its neighbours (each cell is told who its neighbours are when the grid is initialized). Moreover, the TextDisplay class is an observer of every cell (this is also set up when the grid is initialized). The cell’s array of observers does not distinguish what kinds of observers are actually in the array (so a cell could have arbitrary cells or displays subscribed to it). When the time comes to notify observers, you just go through the array and notify them. However, not all observers want to be notified at all times. Displays want to be notified whenever the cell’s state changes, so that their display will be accurate. Neighbouring cells, however, only want to be notified when a cell has been switched by the user, because they will then change their state as well. However, since this latter change of state was not the result of a switch call, their neighbours should not change state, and therefore should not be notified (otherwise, the switching would cascade throughout the grid, which is not how the game works).
So there are two kinds of subscriptions: subscriptions to all events, and subscriptions to switch events only. The file observer.h has an enumeration for these subscription types, and the class Observer has a pure virtual method whereby an observer object can indicate what kind of a subscriber it is. The cells will use this information to determine which observers need to be notified on a given event.
You are to overload operator for the text display, such that the entire grid is printed out when this operator is invoked. Each on cell prints as X and an off cell prints as (i.e., underscore). Further, you are to overload operator for grids, such that printing a grid invokes operator for the text display, thus making the grid appear on the screen.
When you run your program, it will listen on stdin for commands. Your program must accept the following commands:

  • new n Creates a new n × n grid, where n ≥ 1. If there was already an active grid, that grid is destroyed and replaced with the new one.
  • init Enters initialization mode. Subsequently, read pairs of integers r c and set the cell at row r, column c as on. The top-left corner is row 0, column 0. The coordinates -1 -1 end initialization mode. It is possible to enter initialization mode more than once, and even while the game is running. When initialization mode ends, the board should be displayed.
  • game g Once the board has been initialized, this command starts a new game, with a commitment to solve the game in g moves or fewer.
  • switch r c Within a game, switches the cell at row r, column c on or off, and then redisplays the grid.

The program ends when the input stream is exhausted or when the game is won or lost.
The game is lost if the board is not cleared within g moves. You may assume that inputs are valid.
If the game is won, the program should display Won to stdout before terminating; if the game is lost, it should display Lost. If input was exhausted before the game was won or lost, it should display nothing.
Note: Your program should be well documented and employ proper programming style. It should not leak memory. Markers will be checking for these things.
To submit: Submit your solution. You must include a Makefile, such that issuing the
command make will build your program. The executable should be called a4q3a.
Note: there is no sample executable for this problem, and no Marmoset tests. This problem will be entirely hand-marked. In this problem, you will adapt your solution from problem 3a to produce a graphical display. You are provided with a class Xwindow (files window.h and window.cc), to handle the mechanics of getting graphics to display. Declaring an Xwindow object (e.g., Xwindow xw;) causes a window to appear. When the object goes out of scope, the window will disappear (thanks to the destructor). The class supports methods for drawing rectangles and printing text in five different colours. For this assignment, you should only need black and white rectangles.
To make your solution graphical, you should carry out the following tasks:

  • Create a GraphicsDisplay class as a subclass of the abstract base class observer,and register it as an observer of each cell object. It should subscribe to all events, not just switch events.
  • The class GraphicsDisplay will be responsible for mapping the row and column numbers of a given cell object to the corresponding coordinates of the squares in the window.
  • Your main function will create a window, and pass a reference to this window to your GraphicsDisplay object, which will use this reference to update the contents of the window.
  • Your cell objects should not have to change at all.

The window you create should be of size 500×500, which is the default for the Xwindow class. The larger the grid you create, the smaller the individual squares will be.
Note: to compile this program, you need to pass the option -lX11 to the compiler. For example:

g++ *.cc -o a4q3b -lX11

Note: Your program should be well documented and employ proper programming style. It should not leak memory (note, however, that the given XWindow class leaks a small amount of memory; this is a known issue). Markers will be checking for these things.
To submit: Submit your solution. You must include a Makefile, such that issuing the command make will build your program. The executable should be called a4q3b.

Problem 4

In this problem you will have a chance to implement the Decorator pattern. The goal is to write an extensible text processing package. You will be provided with two fully-implemented
classes:

  • TextProcessor (textprocessor.{h,cc}): abstract base class that defines the interface to the text processor.
  • Echo (echo.{h,cc}): concrete implementation of TextProcessor, which provides default behaviour: it echoes the words in its input stream, one token at a time.

You will also be provided with a partially-implemented mainline program for testing your text processor (main.cc).
You are not permitted to modify the two given classes in any way.
You must provide the following functionalities that can be added to the default behaviour of Echo via decorators:

  • dropfirst n Drop the first n characters of each word. If n is greater than the length of some word, the following word is not affected.
  • doublewords Double up all words in the string.
  • allcaps All letters in the string are presented in uppercase. Other characters remain unchanged.
  • count c The first occurrence of the character c in the string is replaced with 1. The second is replaced with 2, the tenth is replaced with 10, and so on.

These functionalities can be composed in any combination of ways to create a variety of custom text processors.
The mainline interpreter loop works as follows:

  • You issue a command of the form source-file list-of-decorators. If source-file is stdin, then input should be taken from cin.
  • The program constructs a custom text processor from list-of-decorators and applies the text processor to the words in source-file, printing the resulting words, one per line.
  • You may then issue another command. An end-of-file signal ends the interpreter loop.

An example interaction follows (assume sample.txt contains Hello World):

sample.txt doublewords dropfirst 2 count l
12o
34o
r5d
r6d
sample.txt allcaps
HELLO
WORLD

Your program must be clearly written, must follow the Decorator pattern, and must not leak memory.
To submit: Submit your solution. You must include a Makefile, such that issuing the command make will build your program. The executable should be called a4q4.