Console Input in Java
Console input in Java is
cumbersome. It uses the java.io package,
which must be imported into the program.
For console input, the keyboard is called System.in. But it is not as
simple to use as console output, where the computer monitor is called System.out. Where we can just put something like
System.out.println (name + "'s age is " + age);
in a program, we cannot
do the same with input.
Java like most languages
buffers input. That means that keystrokes are stored in a
temporary location in memory called a buffer.
Any backspace or delete characters are used to clean up the input string.
For example, suppose that you make a mistake while typing in some data
and then decide to change what you have typed by using the backspace key. The entire string, along with the backspace
character will be stored in a buffer.
Then before the string is sent to the program, it is cleaned up with all
deletions removed.
H |
e |
l |
l |
o |
<sp> |
A |
o |
<bs> |
l |
i |
c |
e |
<enter> |
<sp> stands for
the space bar, <bs> stands for the backspace key, and <enter>
stands for the enter key. Here, the
backspace immediately follows the o, so both the o and the backspace will be
removed. Then the cleaned up string will
be sent for use by the program. It would
look as follows:
H |
e |
l |
l |
o |
<sp> |
A |
l |
i |
c |
e |
<enter> |
If Java did not have
buffered input, all input would have to be typed very carefully, since errors
could not be corrected.
Input and output in Java
(and most other languages) arrive and leave in streams. These are strings
of characters, like "Hello Alice" above. A stream of characters is read character by
character, by a program, but methods associated with the BufferedReader can
read an entire line at a time. The one
we will use most often is readLine. Notice that this is similar to println, which
we used with output to the console screen.
The characters are taken
from the input stream by the InputStreamReader. As mentioned above, the keyboard where the
characters are produced is called System.in.
So we have to get a new instance of the InputStreamReader with System.in
as the parameter. Since what we really
want to work with is the BufferedReader, we do not have to give a specific name
to the InputStreamReader. So when we
get a buffer, stdin, for input, we use the following statement:
BufferedReader stdin = new BufferedReader (new
InputStreamReader (System.in));
The buffer is often
named stdin, which is short for standard input.
After we have a reader,
we can read a string of data using stdin.readLine (). If we want the result stored in a String variable
called name, we can put
name = stdin.readLine ();
in our program.
But if what we want is
the person’s age, an integer, there is an additional problem. The data might be entered incorrectly. The user might make a mistake and type a
letter instead of a number. Or the input
might contain a decimal point, making the result a decimal number and so not an
integer. Because of this, Java is set up
to try to make sense of the
input. The input comes in as a string of
characters.
2 |
1 |
<enter> |
|
|
Java tries to interpret
this as an integer using a method called parseInt. This method is in a class called Integer.
If the characters do represent an integer, the method sends the integer
to the program. In the example above,
this is the number 21. But suppose that
by mistake you type in 21a instead.
2 |
1 |
a |
<enter> |
|
This cannot be
interpreted as an integer. Since Java
has no idea what you meant, it throws an
exception. That means that it simply
tells the program that a mistake has occurred, and then lets the program decide
what to do. The program has to catch the exception and do something
about it. The something is often just
the display of an error message to warn the user that there is a problem.
The kind of exception
created here is called a NumberFormatException.
It is thrown any time that a numerical input is expected, but not
received. This error is an instance of a
more general class of errors called IOExceptions. When using a BufferedReader, you always have
to catch an IOException.
Because so much has to
be done in order to read some data, we usually do the reading in a separate
method. This method includes the try-catch block, the declaration of the
BufferedReader, and all the reading. And
since it is confusing to have to enter data without knowing what is wanted,
each read statement is usually preceded by an output statement that prompts the user for what kind of data
is expected.
A sample method is shown
below.
// A method to read data from the keyboard. It uses a buffered reader.
public void readData ()
{
try
{
BufferedReader stdin = new BufferedReader (new
InputStreamReader (System.in));
System.out.print ("Name: "); // Prompt for the person’s name.
name = stdin.readLine (); // Read in the name as a String.
System.out.print ("Age: "); // Prompt for the person’s age.
age = Integer.parseInt (stdin.readLine ()); // Interpret the input as an integer.
}
catch (NumberFormatException e){ System.out.println
("Invalid numerical input.");}
catch (IOException e) { System.out.println ("Invalid input.");}
} // method readData
If this is a method in
your program, and the data entered is 21a, the console screen will appear as
follows:
A method like the one
above can be copied directly into a program and used. More lines can be added for additional
data. For example, if you want the
person’s birth year, you could add
System.out.print ("Year of Birth: ");
year = Integer.parseInt (stdin.readLine ());
Note that you can use
print instead of println so that the data entry will be on the same line as the
prompt.
An entire program that
uses this method follows. Type it in and
see how it works.
import java.io.*;
/* An application with a
class that reads information about a person from the keyboard and then displays
the data on the screen. */
public class People
{
public static void main (String [] args)
{
Person person = new Person ();
person.readData ();
person.displayAge ();
} // main method
} // class People
// Class that reads in a
person’s name and age and then displays the result.
class Person
{
private String name;
private int age;
// A method to read data from the keyboard using a buffered
reader.
public void readData ()
{
try
{
BufferedReader stdin = new BufferedReader (new
InputStreamReader (System.in));
System.out.print ("Name: ");
name = stdin.readLine ();
System.out.print ("Age: ");
age = Integer.parseInt (stdin.readLine ());
}
catch (NumberFormatException e){ System.out.println
("Invalid numerical input.");}
catch (IOException e) { System.out.println ("I/O error.");}
} // method readData
// Method that displays the name and age of a person.
public void displayAge ()
{
System.out.println (name + "'s age is " +
age);
} // method displayAge
} // class Person
We can use the age
information entered to draw some conclusions about the person. The following program does just that.
import java.io.*;
// An application with a
class that provides information about a person.
class People
{ public static void main (String [] args)
{ Person person =
new Person ();
person.readData ();
person.displayAge ();
person.checkAge ();
} // main method
} // class People
/* Class that reads
information about a person's name and age and then uses the age to provide
additional information about the person. */
class Person
{
private String name;
private int age;
// A method to reads data from the keyboard. It uses a buffered reader.
public void readData ()
{ try
{ BufferedReader
stdin = new BufferedReader (new InputStreamReader (System.in));
System.out.print ("Name: ");
name = stdin.readLine ();
System.out.print ("Age: ");
age = Integer.parseInt (stdin.readLine ());
}
catch (NumberFormatException e){ System.out.println
("Invalid numerical input.");}
catch (IOException e) { System.out.println ("I/O error.");}
} // method readData
// Method that displays the name and age of a person.
public void displayAge ()
{ System.out.println
(name + "'s age is " + age);
} // method displayAge
public void checkAge ()
{ if (age >= 21)
System.out.println (name + " is old enough
to drink.");
else
if (age >= 18)
System.out.println (name + " is old enough
to vote.");
else
System.out.println (name + " has a way to
go yet.");
} // method checkAge
} // class Person