Assignment 13: Multi-dimensional arrays and file IO

The goal of this assignment is the practice (1) using a multi-dimensional array to store tabular data, and (2) using File IO to store data between runs of the program.

As usual, make a new directory for this project and cd into it.

1. Introduction

We've seen in class an example of how to store an addition table in a two-dimensional array. This time we will do something similar, but with a multiplication table. Moreover, we will save the results to a file, and then read that file back in, printing it out. You will do this by filling in the blanks in files already started for you.

Copy the following files from the class directory:

> cp /homeemp/tvandrun/pub/241/TableWriter.java .
> cp /homeemp/tvandrun/pub/241/TableReader.java .

2. Writing a multiplication table

Inspect the file TableWriter.java and understand how it works (at least what's written so far): It first asks the user for the two "maxes", that is, the limits on the multiplication table (the greatest values of the multiplicands). These are also the numbers of rows and columns, respectively, in a multiplication table.

Next, it creates a new two-dimensional array to store the table. The number of rows and columns are the sizes of its dimensions.

Then it "populates" the table by a double loop (iterating through the two dimensions), and storing at each location the product of the indices. Actually, it stores the product of the indices plus one; the plus one is because the indices are zero through the max minus one, but we are interested in the products of one through the max.

Finally, it prints out the table to the screen, similar to how we did in class.

Compile and run, and use it to generate a multiplication table.

Now it's your turn. We want to save this table to a file. The difficult part is to find a way format the file in which you are storing the information. For example, you could print to the the file the same way we are printing to the screen--- make it line up in columns like a table. However, we need to think ahead to when we'll be reading the file back in. We know only how to read in a line at a time. That means if we had a line like

        23     34     62     43    23

we would know only how to read in the entire line, storing it as a string. To get at the individual numbers, we would have to slice up the string where the spaces are. Given enough time, you should be able to write code which will use String methods extract the individual numbers (and I encourage you to think through the problem and think about how you would do it). However, there is an easier way. We could print one number per line, and then when we read in the file later, we can easily read one number at a time. Thus, the table

      1   2   3   4 
      2   3   4   5
      3   4   5   6

Would be stored like

1
2
3
4
2
3
4
5
3
4
5
6

The downside to this is that this would also be the way we would store the table

      1   2   3   4   2   3
      4   5   3   4   5   6

How can we differentiate them? Well, we could begin the file by indicating the dimensions of the table-- the first line giving the number of row, the second line giving the number of columns. Thus the earlier table would be stored like

4
3
1
2
3
4
2
3
4
5
3
4
5
6

Summing up, if we have table

   x0,0 x0,1 x0,2 ...  x0,m
   x1,0 x1,1 x1,2 ...  x1,m
   ...                  ...
   xn,0 xn,1 xn,2 ...   xn,m

we would store it as

n
m
x0,0
x0,1
x0,2
...
x0,m
x1,0
x1,1
x1,2
...
x1,m
...
xn,0
xn,1
xn,2
...
xn,m

So, first uncomment the try block. All the file IO is going to happen there, so that if an IOException is thrown, the catch block will take care of it. Follow these steps:

  1. Ask the user for the name of a file.
  2. Use the file name to make a FileOutputStream. Remember, the constructor of FileOutputStream accepts a String--- the name of the file to open for output.
  3. Make a PrintWriter based on the FileOutputStream. Remember, the constructor of PrintWriter accepts a FileOutputStream.
  4. Write the number of rows to the file
  5. Write the number of columns to the file
  6. Loop over the table, writing each element to the file
  7. Close the print writer.

Now compile and run, and look at the file you have produced to make sure it works right.

3. Reading a multiplication table

Open the file TableReader.java. This program is to read files generated by TableWriter and print out a nicely formatted table. So far it, it asks the user for a file name and (inside a try block) makes a new BufferedReader. Add the following in the try block:

  1. Read in the number of rows and number of columns. Remember, these are in the first two lines of the file.
  2. Make a new table.
  3. Populate the table, reading in values from the file. Remember that when you read in a line from the file, it is a String; you need an int to store in the array. Use the method readNextInt to read in the values as ints.
  4. Close the buffered reader.
  5. Print out the table.

5. Turn in

Create the script file as before (cat--only files you've written or changed, rm, compile, and run)

 > a2ps -P sp (the name of the script file)

(This will print "two up", meaning two pages shown next to each other on one pice of paper. If you use a2ps on a Java file, it will format it nicely like in the handouts I've given in class. The command lpr works similarly except it does no formatting and doesn't print two up by default.)

Then turn in the hard copy by 5:00, Fri, Apr 29.


Thomas VanDrunen
Last modified: Mon Apr 25 15:20:13 CDT 2005