CS 121 – Intro to Programming:Java - Lecture 11 Announcements
Next Owl assignment up, due Friday (it’s short!)
Programming assignment due next Monday morning
Preregistration advice: More computing? Take 191B, or - if you’re really thriving in this class - 187 (come see me about this)
Final exam: 12/19, 8 AM
Topics for today:
File IO - How to read from, write to
external files
Exceptions will also get some attention
import java.util.Scanner;
import java.io.*;
public class DisplayFile{
public static void main(String[] args) throws IOException {
String fileName;
Scanner nameReader = new Scanner(System.in);
System.out.println("Enter a file name");
fileName = nameReader.nextLine();
Scanner scan = new Scanner(new FileReader(fileName));
while(scan.hasNext()){
System.out.println(scan.nextLine());
}
scan.close();
} }
import java.util.Scanner;
import java.io.*;
public class Echo{
String fileName; // external file name
Scanner scan; // reads from external file
public Echo(String f) throws IOException
{
fileName = f;
scan =
new Scanner(new FileReader(fileName));
}
public void readLines(){
while(scan.hasNext()){
processLine(scan.nextLine());
}
scan.close();
}
public void processLine(String line){
System.out.println(line);
}
}
import java.util.Scanner;
import java.io.*;
public class ReadDriver{
public static void main(String[] args)
throws IOException {
String fileName;
Scanner nameReader = new Scanner(System.in);
System.out.println("Enter a file name");
fileName = nameReader.nextLine();
Echo e = new Echo(fileName);
e.readLines();
} }
import java.io.*;
public class LineCount extends Echo{
private int count = 0;
public LineCount(String f) throws IOException {
super(f); }
public void processLine(String line){count++;}
public void reportLineCount(){
System.out.println("Line count: " + count);
} }
import java.io.*;
import java.util.*;
public class WriteFile{
public static void main(String[] args) throws IOException {
String fileName;
System.out.println("Enter a file name. It will hold output");
Scanner nameReader = new Scanner(System.in);
fileName = nameReader.nextLine();
PrintWriter writer = new PrintWriter(fileName);
Scanner scan = new Scanner(System.in);
String s = " "; // a String of length 1
System.out.println("Enter text, end with 2 returns");
while(s.length() > 0){
s = scan.nextLine();
writer.println(s);
}
writer.close();
// now echo the file back to the console Echo e = new Echo(fileName);
System.out.println("Here comes the echo");
System.out.println();
e.readLines();
} }
Our next example ilatlstrues a bizzare
anodecte that ciurctaled on the web seevral
years ago, and casued wiesrpdead giglges
among all who saw it. The story corecnns
an exereipmnt by Brtiish reehrsaecrs that
put forawrd the foiwlolng arguemnt: it turns
out that if you take a seibsnle body of text,
exartct each word, leave the first two and
last two letters of every word unoctuhed, but
then raondmly rernaarge the rest - that is,
the mildde, then the enuisng text is
colpmteely unbdasdearnlte.
import java.util.*;
import java.io.*;
public class ScrambleDriver{
public static void main(String[] args) throws
IOException {
Scanner scan = new Scanner(System.in);
System.out.println("enter file name");
String fileName = scan.next();
TextScramble scram = new
TextScramble(fileName);
scram.readLines();
} }
import java.io.*;
import java.util.*;
public class TextScramble extends Echo{
Random r = new Random();
String blank = " ";
public TextScramble(String f) throws IOException {
super(f);
}
public void processLine(String line){
String s = blank;
String answer = ""; char[] mid;
StringTokenizer str = new StringTokenizer(line);
while(str.hasMoreTokens()){
s = str.nextToken();
if (s.length() < 6) answer = answer+ s + blank;
else { // carve up the token..
String front = s.substring(0,2);
String back = s.substring(s.length() - 2, s.length());
String middle = s.substring(2,s.length() -2);
mid = middle.toCharArray(); // make middle an array shuffle(mid); // shuffle
middle = new String(mid); // transform back to a String answer = answer +front + middle + back + blank; }
} // end loop processing all tokens in line System.out.println(answer);
}
Java has a shadow system for handling errors:
Exceptions
This is a system of classes and objects that employ
special machinery for detectings errors and shifting
responsibilites for handling these problems
Java recognized two kinds of errors:
Unchecked exceptions: errors that occur because of
flaws in logical thinking on the part of the programmer
(e.g. division by 0)
Checked exceptions: errors that can be expected to
occur, and may occur despite your best efforts to avoid
them (trying to read from a file that doesn’t exist)
public class Except0{
public static void main(String[] args){
int k; int a = 3; ; int b = 0;
k = a/b;
}
}
Java reports:
Exception in thread "main" java.lang.ArithmeticException: / by zeroÏÏ§Ï at Except0.main(Except0.java:7)
Java has special machinery, the try/catch
construction, for dealing with exceptions
(handling exceptions)
An exception is handled if your code
detects the error and takes some action in
response -- as in the next example.
public static void main(String[] args){
int k; int a = 3; int b = 0;
try{
k = a/b;
}
catch(ArithmeticException e) {
System.out.println( e);
} }
}
Java reports:
Ïjava.lang.ArithmeticException: / by zero ÏϧÏ
public class Except3{
public static void main(String[] args){
String s = "98.6";
int n;
try{
n = Integer.parseInt(s);
System.out.println(n*n); } catch(Exception e)
{
e.printStackTrace();
} } }
Ï java.lang.NumberFormatException: For
input string: "98.6"
ÏÏ§Ï at
java.lang.NumberFormatException.forInput
String(NumberFormatException.java:48)
ÏÏ§Ï at
java.lang.Integer.parseInt(Integer.java:456)
ÏÏ§Ï at
java.lang.Integer.parseInt(Integer.java:497)
ÏÏ§Ï at Except3.main(Except3.java:8)
ÏϧÏ
A more realistic example - you are supposed to enter
an integer, representing your name (the program then
reports your age for next year..)
Some interaction:
Ï enter your age
¼¼§Ï 39e
ÏÏ§Ï Bad input. 39e is not an integer. You must
input an integer
Ï enter your age
¼¼§Ï 39
ÏÏ§Ï next year you will be 40
ÏϧÏ
import java.io.*;
import java.util.*;
public class IntegerInput{
public static void main(String[] args){
int n = -1;
Scanner scan = new Scanner(System.in);
while (n < 0) {
System.out.println("enter your age");
try {
if (scan.hasNextInt()) n = scan.nextInt();
else { // non integer submitted String userInput = scan.next();
throw new Exception("Bad input. "+ userInput + " is not an integer. You must input an integer");
}
}
catch (Exception e)
{ System.out.println(e.getMessage()); } }
System.out.println("next year you will be " + (n + 1));
} }
What does throw do: it “presents” an exception object of the indicated kind at a new location in the program..
What if you enter a negative number? Not handled
very well
(No message)..
enter your age
¼¼§Ï -39
enter your age
One way to handle this: make a new kind of Exception..
public class NegativeException extends Exception{
public NegativeException() { };
public NegativeException(String msg){
super(msg);
} }
And then:
while (n < 0) {
System.out.println("enter your age");
try {
if (scan.hasNextInt()) n = scan.nextInt();
else {
String userInput = scan.next();
throw new Exception("Bad input. "+ userInput + "is not an integer. You must input an integer");
}
if (n < 0) throw new NegativeException();
}
catch (NegativeException e)
{ System.out.println("age must be >= 0"); } catch (Exception e)
{ System.out.println(e.getMessage()); } } // end while
System.out.println("next year you will be " + (n + 1));
Notice: two kinds of exceptions, more specific one first
One more example:
You have a data file of numerical data, integers,
one per line
It may contain errors (deep space information?)
You want to compute the average value of the
entries - but you’re happy just to skip over the
bad data
Here is nums.txt
50
60
3e
10
Here’s the output:
Ï Bad Entry: 3e
Ï 40.0
import java.io.*;
import java.util.*;
public class NumberReader { String fileName;
int sum = 0;
int count = 0;
Scanner scan;
public NumberReader(String f) throws IOException { fileName = f;
scan = new Scanner(new FileReader(fileName));
}
public void readLines(){while(scan.hasNext()){
processLine(scan.nextLine());
}
scan.close();
}
Handle
IOEX when I’m called
public void processLine(String line){
try{
int num = Integer.parseInt(line);
sum += num;
count++;
}
catch(Exception e)
{System.out.println("Bad Entry: " + line);}
}
public void printResult(){
System.out.println((double)sum/count);
} }
public class NumDriver{
public static void main(String[] args){
try{
NumberReader num
= new NumberReader("nums.txt");
num.readLines();
num.printResult();
}
catch(Exception e) {e.printStackTrace();}
} }
This is tacky:
public class ReadDriver{
public static void main(String[] args)
throws IOException {
String fileName;
Scanner nameReader = new Scanner(System.in);
System.out.println("Enter a file name");
fileName = nameReader.nextLine();
Echo e = new Echo(fileName);
e.readLines();
} }
public class ReadDriver{
public static void main(String[] args) { try{
String fileName;
Scanner nameReader = new Scanner(System.in);
System.out.println("Enter a file name");
fileName = nameReader.nextLine();
Echo e = new Echo(fileName);
e.readLines();
}
Catch(IOException e){System.out.println(e);}
} }