Java Lab Assignment 1

profilebreakerbuck
lab2.pdf

1

CMPS 12M

Introduction to Data Structures Lab

Lab Assignment 2

The goal of this assignment is to practice using command line arguments, file input-output, and manipulation

of Strings in java. File input-output and command line arguments will be necessary to complete some future

assignments.

Command Line Arguments

In a Java program, function main() reads the command line from which it was called, then stores the tokens

on that line in the args array. Use the following Java program to create an executable jar file called

CommandLineArguments (see lab1 to learn how to do this)

// CommandLineArguments.java

class CommandLineArguments{

public static void main(String[] args){

int n = args.length;

System.out.println("args.length = " + n);

for(int i=0; i<n; i++) System.out.println(args[i]);

}

}

then do %CommandLineArguments zero one two three four and observe the output. Run it with

several other sets of tokens on the command line. These tokens are called command line arguments, and can

be used within a program to specify and modify the program's behavior. Typically command line arguments

will be either strings specifying optional behavior, text to be processed by the program directly, or names of

files to be processed in some way.

File Input-Output

The java.util package contains the Scanner class, and the java.io package contains classes PrintWriter and

FileWriter. These classes perform simple input and output operations on text files. Their usage is illustrated

in the program FileCopy.java below, which merely copies one file to another, i.e. it provides essentially

the same functionality as the Unix command cp (with respect to text files only.)

// FileCopy.java

// Illustrates file IO

import java.io.*;

import java.util.Scanner;

class FileCopy{

public static void main(String[] args) throws IOException{

Scanner in = null;

PrintWriter out = null;

String line = null;

int n;

// check number of command line arguments is at least 2

if(args.length < 2){

System.out.println("Usage: FileCopy <input file> <output file>");

2

System.exit(1);

}

// open files

in = new Scanner(new File(args[0]));

out = new PrintWriter(new FileWriter(args[1]));

// read lines from in, write lines to out

while( in.hasNextLine() ){

line = in.nextLine();

out.println( line );

}

// close files

in.close();

out.close();

}

}

As you can see, the Scanner constructor takes a File object for initialization, which is itself initialized by a

String giving the name of an input file. The Scanner class contains (among others) methods called

hasNextLine() and nextLine(). Read the documentation for Scanner at

http://docs.oracle.com/javase/8/docs/api/

to learn about the proper usage of these methods. The PrintWriter constructor takes a FileWriter object for

initialization, which is in turn initialized by a String giving the name of an output file. PrintWriter contains

methods print() and println() that behave identically to the corresponding methods in System.out,

except that output goes to a file instead of stdout. Note that the FileWriter initialization can fail if no file

named args[1] exists in the current directory. If it fails, it will throw an IOException. This is a checked

exception, which cannot be ignored, and therefore function main() must either catch the exception, or throw

it up the chain of function calls. (In the case of function main(), the "calling function" is the operating

system). In this example, we deal with this by declaring main() to throw an IOException, causing the

program to quit if the exception is encountered. Similar comments apply to the initialization of the Scanner

object. See the java documentation for more details.

Compile and run FileCopy.java, and observe that a Usage statement is printed if the user does not provide

at least two command line arguments. This Usage statement assumes that the program is being run from an

executable jar file called FileCopy. All of your programs that take command line arguments should include

such a usage statement.

String Tokenization

A common task in text processing is to parse a string by deleting the surrounding whitespace characters,

keeping just the discrete words or “tokens” that remain. A token is a maximal substring containing no

whitespace characters. For instance, consider the preceding sentence to be a string. The 10 tokens in this

string are: "A", "token", "is", "a", "maximal", "substring", "containing", "no", "whitespace", "characters.".

Whitespace here is defined to mean spaces, newlines, and tab characters. This is one of the first tasks that a

compiler for any language such as Java or C must perform. The source file is broken up into tokens, each of

which is then classified as: keyword, identifier, punctuation, etc. Java's String class contains a method called

split() that decomposes a string into tokens, then returns a String array containing the tokens as its elements.

Compile and run the following program FileTokens.java illustrating these operations.

3

// FileTokens.java

// Illustrates file IO and tokenization of strings.

import java.io.*;

import java.util.Scanner;

class FileTokens{

public static void main(String[] args) throws IOException{

Scanner in = null;

PrintWriter out = null;

String line = null;

String[] token = null;

int i, n, lineNumber = 0;

// check number of command line arguments is at least 2

if(args.length < 2){

System.out.println("Usage: FileCopy <input file> <output file>");

System.exit(1);

}

// open files

in = new Scanner(new File(args[0]));

out = new PrintWriter(new FileWriter(args[1]));

// read lines from in, extract and print tokens from each line

while( in.hasNextLine() ){

lineNumber++;

// trim leading and trailing spaces, then add one trailing space so

// split works on blank lines

line = in.nextLine().trim() + " ";

// split line around white space

token = line.split("\\s+");

// print out tokens

n = token.length;

out.println("Line " + lineNumber + " contains " + n + " tokens:");

for(i=0; i<n; i++){

out.println(" "+token[i]);

}

}

// close files

in.close();

out.close();

}

}

What to turn in

Write a java program called FileReverse.java that takes two command line arguments giving the names

of the input and output files respectively (following the preceding examples). Your program will read each

4

line of input, parse the tokens, then print each token backwards to the output file on a line by itself. For

example given a file called in containing the lines:

abc defg

hi

jkl mnop q

rstu v

wxyz

the command %FileReverse in out will create a file called out containing the lines:

cba

gfed

ih

lkj

ponm

q

utsr

v

zyxw

Your program will contain a recursive method called stringReverse() with the following signature:

public static String stringReverse(String s, int n)

This function will return a String that is the reversal of the first n characters of s. Note that reversing a String

recursively is very similar to reversing an array. Study the methods in the String class documented at

http://docs.oracle.com/javase/8/docs/api/ to determine how this might be done. See especially the instance

methods charAt() and substring(), as well as the static method valueOf(). Base your reversal strategy

on one of the recursive methods reverseArray1() or reverseArray2() discussed in class. Use

stringReverse() to perform the reversal of tokens from the input file.

Submit the files README, Makefile, and FileReverse.java to the assignment name lab2. This is not a

difficult assignment, since most of the items mentioned here should be review, but please don't wait until the

last minute to start.