Lab exercise #2: Experimenting with input and output

Course links

External links

The objective

Our goal for today is to implement a lister: a program that simply writes the contents of text files to standard output, with the option of numbering the lines.

Part 1: A basic lister

The author of our textbook provides the source code for a file lister (Figure 2.16 on page 56), and it may be useful to look over this source code as preparation for writing our own more or less equivalent program.

A simple way to get started would be to take Weiss's lister and tweak it a little bit. (For instance, one simple improvement that we could make immediately would be to have the lister write its error messages to System.err rather than to System.out.) As Weiss reminds us, his source code is copyrighted, which means that we can rewrite it for our own purposes only if (a) we get Weiss's permission, or (b) we are prepared to argue, in court if necessary, that our rewriting is a "fair use" of his source code under section 107 of the Copyright Act (Title 17 of the United States Code).

In this lab setting, we're on pretty safe ground, since the "fair use" limitation on copyrights allows us to copy and modify Weiss's code so long as we're engaged in "teaching ..., scholarship, and research" and not trying to undermine "the potential market for or value of the copyrighted work." On the other hand, if we ever wanted to incorporate our modified file lister into some application with a non-educational purpose, we might well find that it would be illegal to do so.

A better approach is to base our work on code with similar functionality that is either not copyrighted at all or is available under some license that explicitly allows us to make derivative works for any purpose. I have written just such a file lister and published it on the Web under the GNU General Public License, which permits anyone who receives a copy to modify it for her own purpose. The main condition is that, if you share the resulting derivative work with others, you must give them the source code under the same license, so that the programming community can benefit from your improvements, just as you benefit from having access to the original program.

1. Make a copy of FileLister.java in your own account. Add your names, affiliations, and e-addresses to the authorship section of the opening comment. Revise the copyright line near the end to read something like

   *  Original FileLister program copyright (C) 2008 John David Stone
   *  Modifications and extensions copyright (C) 2008 George Spelvin and
   *      Alexis Cawthorne

2. Read through the code. If any small improvements suggest themselves to you, make them. Explain each of the operations involving input, output, or files.

3. Save and compile the program. Test it to make sure that it behaves as expected; if it doesn't, fix any problems.

Part 2: Line numbering

When the author of our textbook gives long code examples, he presents them as figures in which the lines of code are numbered for quick reference. This is potentially a useful feature for a file lister to have, too.

1. Modify the outputContents method in FileLister.java so that, at the beginning of each line that it copies from a file, it outputs a line number -- 1 for the first line of a file, 2 for the second line, and so on.

2. Once you have this working, adjust the same method so that the line numbers are presented attractively, thus:

     1| This is the first line of the file.
     2| This is the second line.
     3| And the third,
     4| and so on.

Each line number is right-justified in a six-column field and followed by a vertical bar and a space before the actual text from the file begins. (Note that the resulting program may run into problems if anyone runs it on a file containing one million or more lines. You may want to consider throwing an exception in such a case.)

Part 3: Making line numbering a command-line option

The line-numbering facility of your version of FileLister will be much more useful if the user of the program can turn it on and off. The usual way of allowing users to specify such things is to use command-line options.

In this case, for example, a good design would be to have a special string, -n, that could be placed at the beginning or in the middle of a list of files, to switch on line numbering just for those files that follow it. So, for instance, the command line

java FileLister foo.txt bar.txt -n baz.txt quux.txt

would list foo.txt and bar.txt without line numbers, but baz.txt and quux.txt with them. To do without line numbers entirely, the user would just leave out the -n; to turn them on for all the files, the user would place the -n at the beginning of the list of files. (And placing -n at the end of the list would be permitted, but would have no effect.)

1. Give FileLister a static boolean field that indicates whether lines are to be numbered or not.

2. Modify the outputContents method so that it inspects this field and prints out a line number if, and only if, the value stored there is true.

3. Modify the main method so that it checks each command-line argument to see whether it is the string -n and, if so, changes the value stored in the field you added in step 1 of this part.

4. Add a second command-line option, -u, that turns off line numbering for the files that follow it, so that, say,

java FileLister foo.txt bar.txt -n baz.txt -u quux.txt

would cause all four files to be listed but provide line numbers only for baz.txt.

Part 4: Further command-line options

1. Consider what other command-line options might be useful in a file lister. (For some suggestions, type

man cat

at the prompt in a terminal to see what options the authors of the Linux file lister cat chose to implement.)

2. Implement the most useful of those options.