CHAPTER 11
|
Table of Contents
Learning C++:
An Index of Entry Points
2. The A reference document on the basic elements of C++.
3. The Patterns
|
A. Looking for New Classes or Modifications to the Existing
Classes The conclusion, then, is that we can use the built-in stream classes to
handle file manipulation since these classes have their own instantiation
(create), read, and write (store) capabilities. The only word in the list
that might not fit this analysis is 'database'. However, we have already
learned how to link file names to files and database is strictly another
name for our ListOfClasses. In other words, an instance of 'ListOfClasses'
can be seen as a manifestation of a contract database in RAM while a file
holding the same information represents the same database on disk. B. Interface Analysis In earlier programs we spent some time designing the look and feel of
the user interface. For example, we examined how input requests in the
form of prompts or menus might look or how output might appear in columns
on a screen. We must go through a similar process for file input and
output. If the file output is ultimately to be printed for use by human
readers, the design process is similar to that used for screen output. If
the output is to later be read by a computer as file input, the process
should focus on making the input as easy to handle as possible. In our situation, the contract database will be read back by our
program. Therefore, we need to consider such issues as, given that a
person's name may have two, three or more parts, how should we indicate
the end of a name. The same applies for street address, city, and state.
(Consider Las Vegas and New Mexico vs Bismarck and Montana). Notice how
grammar rules tell us to use a comma to separate the city from the state
in writing out addresses. Without this, one could interpret "Las Vegas New
Mexico" as referring, for example, to the city "Las Vegas New" in the
state of "Mexico". This gives us a hint - why not use a delimiter,
that is, a symbol of some kind, to separate the fields of each
contract record. We have been using the idea of delimiter all along without using the
term. For example, the space or blank character is used in C++ to separate
identifiers. That is why we must use the 'underbar, '_', to connect words
if we want them to be part of one identifier name as in MAX_CONTRACTS. We
can't use the space as the delimiter in our contract database because, as
we just observed, names usually have spaces in them. Therefore, as a
somewhat arbitrary but useful choice, let's follow the idea of using
commas. Done! A comma will separate each field of the output. We also need to determine the order in which the fields of each
contract record will be written. Without this information we cannot
correctly write the code to read the data back in. The easiest thing to do
is to follow the same order used in outputting contract data to the
screen. (This will allow us to partially copy the code from 'DisplayInfo'
when we write the function to output contract data to a file.) Thus, the
contract ID will come first, followed by the name of the contractee and
the street address, city, state, and zip code of the office. After these
will come the square footage of the office, the number of desks in the
office and number of days per week the office is to be cleaned - with all
these fields separated by commas. The end of the information concerning
each contract will be indicated by a newline character. The only other addition to the interface analysis involves a brief
description of the prompts and inputs to allow the user to state the input
and output file names. on this. C. Implications for the Program Design Many times in these chapters we have observed that there is more than
one way to develop a program. Some software engineers promote an approach
based more on prototyping than on careful, systematic pre-analysis
and design as has been described in this text. The prototyping approach
suggests that one should start with some analysis and design but be
willing to move sooner into the coding stage to try out one or more
designs. The idea is to experiment with specific designs, perform a
careful analysis of the results of the experimentation, and be willing to
throw out what does not work. Key to this approach is:
Some students, when they hear this, claim they want to try this
approach. However, all they often mean is that they want to get down to
coding without ANY analysis and design. And, they often ignore the other
side of the prototyping approach, the need to:
Although we have not really been acting as prototypers here, some of
the results are the same. At this point we have code that works in some
ways but still needs to be improved. We could see our results so far as
indicating that most of the code works but that we need to change that
aspect dealing with input and output of the database itself. The point
being made here is that we, therefore, know that we can keep most of the
code and even that the part that needs to be changed may have elements
worth salvaging. Having said all that, let's review what needs to be modified to allow
the program to output the database to a file when the user indicates that
he or she wants to quit. Previously, when the user chose to end the
program, nothing happened except for the displaying of a closing message.
That indicates that, unlike when reading in the database - where we could
modify an existing function, some new functionality is needed here. On the
other hand, this functionality is somewhat similar to that used to display
the database on the screen, so maybe we can borrow some of the code used
there. Where can we cleanly fit in this new functionality? Well, every other
user option handled in the function 'ProcessUserChoices' except for the
'quit' option calls a function. Why not have a call to the function that
will handle the output placed in the code for the quit option! The other
possible choice would be to include the code inside
'DisplayClosingMessage', but the very name of that function discourages
its use in this way. We will call this new function 'OutputData'. Does it receive or return
anything? Remember the design pattern
for output functions we developed long ago ? We determined there that
output functions receive one or more items - the data to be output - and
return nothing. Since it is the list of contracts that is to be output,
this analysis implies that it is the list that should be received. Since we have not written a function quite like this
before, it would be wise to work a bit on an algorithm before proceeding
to code. As you probably have already observed, however, new functions
don't usually develop in a vacuum. They can often be built by borrowing
ideas from elsewhere. We have already noticed that we might want to borrow
from the code for 'DisplayAllContracts' since it matches some of the
functionality of this new function - it outputs all of the contracts, even
if the output goes to the screen and not to a file. Also, in the previous
section we studied file output. So, let's see if we can't put together an
algorthm that borrows from both these sets of code. Reviewing the code in the file 'fileio.cpp,
we see that we need get the file name from the user, instantiate a stream
connected to that file, and check the results of the instantiation
process. Examining 'DisplayAllContracts', we see that one way to
accomplish the rest of our goal is to iterate through the list of
contracts and call a function to output each individual contract. Our
algorithm might then look as follows: Writing that algorithm, proved relatively simple but useful. It would
be wise if we also wrote an algorithm for 'ReadInstances' since this too
is a type of code we have never written before. We know we need to ask the
user for the file name where the database was stored and open a stream
attached to that file. Thus, this algorithm will begin much the same as
the previous one. Back in chapter three you learned the
algorithm for reading data from a keyboard. The algorithm for reading from
a file is much the same except that now the stopping condition is the end
of the file. Here then is the algorithm: |
|