CS111, Wellesley College

Lab 11

Wedn/Thur, November 15/16, 2006

Arrays and File I/O

Today's agenda:

To get started: Download the lab11_programs folder from the cs111d account.

I.   System.out.print() vs. System.out.println() (a reminder)

print() and println()are two methods that allow you to print text to the Java console window.

print() prints your text and leaves the cursor at the end of printed text, ready to print the next thing on the same line.

println(), on the other hand, prints your text and then waits at the start of the next line to print the next thing.

This is best demonstrated by example. Each snippet of code produces the window to the right.


		System.out.print("Hi, there!");
		System.out.print("Good");
		System.out.println(" to see you!");

(Note: no spaces between there! and Good )

		System.out.println("Hi, there!");
		System.out.println("Good");
		System.out.println(" to see you!");


		System.out.println("Hi, there!");
		System.out.print("Good");
		System.out.println(" to see you!");

II.   Printing out the contents of an array, reversing an array

Your code for this part goes into the file labArray.java in the folder labArrays in lab11_programs. There are two different ways that you can view some examples of how printArray() and reverseArray() work:

A. Printing out an array

We want to be able to print out the contents of our arrays (so that when we test our array methods, we can print out the arrays to make sure that the methods are working). Let's write a method called printArray(int [] arr) that prints out the contents of the integer array arr on one line. For example, say we have an array B that has the value [2, 4, 6, 8. Then invoking printArray(B) should produce the following in the Java Console window:

[2, 4, 6, 8]

Hint: Use a for loop to traverse the array.

B. Reversing the contents of an array

Now we want to reverse the contents of our array. So, if array C is [0, 1, 2, 3, 4], and we run reverseArray(C), then C's value is [4, 3, 2, 1, 0]. When we have reversed an array, we can use printArray() to see the result! In your main() method, print out the value of each array before and after invoking reverseArray() to check that your reverseArray() actually works. Our test code looks like this:


      	int[] a = { 9, -1, 3, 6, -10}; // creates an array named a
      
		System.out.println("Original a "); 
		printArray(a); // print out the original array
		System.out.println("Reversed a ");
		reverseArray(a); // reverse the array
		printArray(a);   // print out the reversed array
		System.out.println("--------");      
      
  
Important Thing to Know
Note that the method reverseArray() must change the order of elements of the given array. It does not do any printing itself (you may, of course, insert print statements for debugging, and remove or comment out them later).


File Input/Output

It's often useful to be able to read in a file, do some stuff to that file, and then write out a new file. We're going to practice doing that (called File I/O) in Java today.

Some background:

How to open a file (that you plan on writing into)? FileWriter writer = new FileWriter("myNewFile");
How to open a file (that you plan on reading from)? BufferedReader reader = new BufferedReader(new FileReader(fileToReadFrom));
How to get one line read from a file? reader.readLine();
How to write to a file? writer.write("atch atch atchoooooooooooo!");
How to close a file? writer.close();
reader.close();
How to try and catch? try { //opening files and manipulating them goes here
 
 
 
} catch (Exception ex) {
ex.printStackTrace();
}

Part 1a: Writing a text file to the console window, line by line

First, read in the text file called "spaghetti.txt" and print it out to the console window (System.out.println()) one line at a time. You can take a peek at the file spaghetti.txt (in drJava or in any simple text editor). Printing each line of the file to the console is merely a useful intermediate step, to make sure your files are being opened and closed correctly.

To run your program, type this in the Java Interactions pane:
java LineNumber spaghetti.txt

If you forget to tell drJava which file to read from, it will give you an error message like this:

If your program runs correctly, your console output should look like this:

One quirk of drJava is that drJava assumes that any files being read from or written to are in the same folder as the drJava application. We usually like to read from and write to files that are in a folder on our desktop. Hence, the following code sets the path correctly for the files that we will use in today's lab:

        URL u = LineNumber.class.getResource("/LineNumber.class");
        String path = new File(u.toString()).getParent();
        String newpath = path.substring(5,path.length()); 
        newpath = newpath + "/";

The code above sets the string variable newpath to contain the path to your LineNumber.class file. For example, newpath on Sohie's computer is this:
/Users/slee/Desktop/LineNumber

We want all files that LineNumber.java uses or produces to be contained within the LineNumber folder. If you don't use newpath, then drJava is unable to find the spaghetti.txt file. Similarly, if you don't use newpath, any files that you create and write to will not be in the LineNumber folder.

Part 1b: Writing a text file to the console window, word by word

This is very much like what you did above, but this time, write each word on a single line.
A partial view of your output is shown below:

In order to do this, you need to use the split method from the String class. split splits a given string into parts, given a delimiter, and places those parts into an array. For example:

String song = "Old man Dan he's a mean old man";
String alphabet = "a-b-c-d-e-f-g-h-i-j-k-l-m-n-o-p-q-r-s-t-u-v-w-x-y-z";
String [] songwords = null;
String [] letters = null;

songwords = song.split(" "); // delimiter is a space
letters = alphabet.split("-"); // delimiter is a dash

for (int i = 0; i< songwords.length; i++) {
     System.out.println(songwords[i]);
}
System.out.println("***");
for (int i = 0; i< letters.length; i++) {
     System.out.println(letters[i]);
}

Produces this output:
Old
man
Dan
he's 
a
mean
old 
man
***
a
b
c
d
e
.
.
.

Part 2: Writing a new text file that adds line numbers into a supplied text file

Now, your goal is to read in a file and then add line numbers to each line in the file and write out a completely new file (rather than simply printing to the console). Sticking with the same text file as before (spaghetti.txt), the newly created file will look like this:

It's even more useful to do this to actual java programs:
Before:

After:

Notes:

Part 3: Adding padded line numbers to preserve spacing of original file

In this task, you want to build on Task 2 so that all the line numbers are right-aligned in a four-digit space. This maintains the alignment of the original document (see example below which just shows a clip of code).

Original Code

    import java.awt.*;

    public class DoTheHulaHulaDance {
         int numberHulas = 5;
         String HulaDancer1 = "Mark";
         String HulaDancer1 = "Sohie";

         public void Hula () {
               System.out.println("Hula!"+ HulaDancer1);
               System.out.println("Hula again!");
               System.out.println("Are you tired yet?");

         }

With Non-Padded line numbers added

/* line 1 */    import java.awt.*;
/* line 2 */
/* line 3 */    public class DoTheHulaHulaDance {
/* line 4 */         int numberHulas = 5;
/* line 5 */         String HulaDancer1 = "Mark";
/* line 6 */         String HulaDancer1 = "Sohie";
/* line 7 */
/* line 8 */         public void Hula () {
/* line 9 */               System.out.println("Hula!"+ HulaDancer1);
/* line 10 */               System.out.println("Hula again!");
/* line 11 */               System.out.println("Are you tired yet?");
/* line 12 */         }

With right-aligned line numbers (within a field of 4 spaces) added

/* line    1 */    import java.awt.*;
/* line    2 */
/* line    3 */    public class DoTheHulaHulaDance {
/* line    4 */         int numberHulas = 5;
/* line    5 */         String HulaDancer1 = "Mark";
/* line    6 */         String HulaDancer1 = "Sohie";
/* line    7 */
/* line    8 */         public void Hula () {
/* line    9 */               System.out.println("Hula!"+ HulaDancer1);
/* line   10 */               System.out.println("Hula again!");
/* line   11 */               System.out.println("Are you tired yet?");
/* line   12 */         }

Your task is to amend LineNumber.java so that it creates a new file with a right-aligned line number comment at the start of each line. Assume that each line number is allowed a max of 4 digits (in other words, no programs over 9999 lines).

Hint: the number of spaces needed for a number n is log base 10 (n). In Java, log base 10 (n) is done like this:
(int) (Math.log(n)/Math.log(10));