CS140 -- Lab 6
This lab will give you practice:
- using singly linked lists,
- checking for
error conditions in the input. Error checking can be tedious, but it is important
in the real world (sloppy error checking is often exploited by computer viruses
in staging their break-ins to your computer), and
- writing a design document. Before you start this lab, you will need to create and submit a design
document to the TA. The last section of this lab write-up describes what your design
document should contain.
Materials
You will need the following files:
- Executables for the answers are in the directory
/home/bvz/cs140/labs/lab6. As usual, if you have
questions about how these programs should work, try these.
- A sample input file for linenum can be found in brad.
You should make up your own sample data as well.
- You will need to include fields.h and sllist.h from
/home/bvz/cs140/include.
- You will need to link in fields.o and sllist.o from
/home/bvz/cs140/objs.
- You must use my singly-linked list library, sllist, for this lab.
linenum
Write a program called linenum
that takes a filename and an arbitrary number of words from the command
line and then prints the line numbers from the file
on which each of these strings appears.
You must use the fields library to read each line of
input. You should use a dynamically allocated array of singly linked
lists to keep track
of the list of line numbers for each word. Each line of output should
consist of a word and then the line numbers on which it appears. Line
numbers should not be duplicated. The words should be printed in the order
in which they appear on the command line. For example, if the file brad
contains the lines:
ice cream is nice
but chocolate ice
cream is dandy
then the command:
<UNIX> linenum brad cream nice ice Nice
should produce the
output:
cream 1 3
nice 1
ice 1 2
Nice
The words on the command line may be duplicated (e.g., ice may appear twice)
but it is okay to only print that word once in your output. My executable
will duplicate the output for that word, which is also acceptable.
Your output should be formatted as follows:
- The words should be left-justified in a 10 character wide field.
- There should be a single space between the word field and the first line number.
Extra spaces may appear because the word or line number do not fully occupy their
field.
- The line numbers should be right-justified in a 4 digit wide field.
Implementation Advice
The value for a singly-linked list node in my sllist library is a void *.
Normally a linked list node will point to a struct, but in this case you only need to
store one piece of information, the line number, so a struct seems like overkill. Go
ahead and use a struct with one field if you wish. However, if you want to make life
easy on yourself, just malloc space for an integer, store the integer in that space,
and pass a pointer to that integer to the sllist's sll_append function. Here
is some sample code for malloc'ing space for an integer and storing an integer in that space:
int *new_int;
new_int = (int *)malloc(sizeof(int));
*new_int = 3;
Testing Suggestions
I have provided one test file in the lab6 directory, brad to
test your program. However, you should test your program for boundary-type
conditions and command line issues, such as:
- An empty file
- An extremely large file
- Files that have lines with duplicate words
- Command lines with duplicate words
- Files that have lines with duplicate words but the words are
in different case (e.g., nice, Nice, and NICE).
- Command lines with duplicate words but the words are in
different case
- Command lines with too few arguments
- Filenames that do not exist
Design Document
We have already told you one helpful program design technique, which is to incrementally
develop your programs. A second helpful program design technique is to map out your
solution at a high-level before implementing it. Frequently this design technique
involves:
- drawing pictures of what your data structures might look like,
- writing down what error
conditions, boundary conditions, and normal conditions your program needs to handle, and
- writing down pseudo-code or a list to describe the high-level steps that your solution
will entail. You will then replace the pseudo-code or list with actual code.
The design document that Thomas Hooper gave you for lab 4 is one version of a
high-level list of steps to perform.
We have already given you the testing suggestions for this lab. In future labs you will
be asked to create a list of error and boundary conditions.
For this lab we want you to:
- draw on a piece of paper the data structures that you
will be using. It helps
to use concrete data when drawing your data structures, so we want you to draw what
your data structures will look like once the file named brad, which is listed
above, has been fully read. The diagrams you draw should resemble the high-level
ones I draw in class. They do not need to contain pointer addresses, but rather just
the data values that will be stored. It is also permissable to place the data values
in the list nodes, like I do in class, rather than in separate structures that are
then pointed to by the value fields in the list nodes.
- write down a short list of steps that you will need to perform
in order to implement a solution to linenum. You should incrementally
develop your program by implementing these steps one at a time.
What to Submit
You will submit your design document in the lab when the TA calls for it.
Submit a source file named linenum.c via the normal submission procedure.