> ### Section 2.4
> Text Input and Output

> FOR SOME UNFATHOMABLE REASON, Java seems to lack any reasonable built-in subroutines for reading data typed in by the user. You've already seen that output can be displayed to the user using the subroutine `System.out.print`. This subroutine is part of a pre-defined object called `System.out`. The purpose of this object is precisely to display output to the user. There is a corresponding object called `System.in` that exists to read data input by the user, but it provides only very primitive input facilities, and it requires some advanced Java programming skills to use it effectively.

> There is some excuse for this, since Java is meant mainly to write programs for Graphical User Interfaces, and those programs have their own style of input/output, which is implemented in Java. However, basic support is needed for input/output in old-fashioned non-GUI programs. Fortunately, it is possible to extend Java by creating new classes that provide subroutines that are not available in the classes which are a standard part of the language. As soon as a new class is available, the subroutines that it contains can be used in exactly the same way as built-in routines.

> For example, I've written a class called `TextIO` that defines subroutines for reading values typed by the user. The subroutines in this class make it possible to get input from the standard input object, `System.in`, without knowing about the advanced aspects of Java that are needed to use `System.in` directly. `TextIO` also contains a set of output subroutines. The output subroutines are similar to those provided in `System.out`, but they provide a few additional features. You can use whichever set of output subroutines you prefer, and you can even mix them in the same program.

> To use the `TextIO` class, you must make sure that the class is available to your program. What this means depends on the Java programming environment that you are using. See Appendix 2 for information about programming environments. In general, you just have to add the compiled file, `TextIO.class`, to the directory that contains your main program. You can obtain the compiled class file by compiling the source code, TextIO.java.

> The input routines in the `TextIO` class are static member functions. (Static member functions were introduced in the previous section.) Let's suppose that you want your program to read an integer typed in by the user. The `TextIO` class contains a static member function named `getInt` that you can use for this purpose. Since this function is contained in the `TextIO` class, you have to refer to it in your program as `TextIO.getInt`. The function has no parameters, so a call to the function takes the form "`TextIO.getInt()`". This function call represents the `int` value typed by the user, and you have to do something with the returned value, such as assign it to a variable. For example, if `userInput` is a variable of type `int` (created with a declaration statement "`int userInput;`"), then you could use the assignment statement

> `userInput = TextIO.getInt();`

> When the computer executes this statement, it will wait for the user to type in an integer value. The value typed will be returned by the function, and it will be stored in the variable, `userInput`. Here is a complete program that uses `TextIO.getInt` to read a number typed by the user and then prints out the square of the number that the user types:

>                     public class PrintSquare {

>                       public static void main(String[] args) {

>                          // A program that computes and prints the square
>                          // of a number input by the user.

>                          int userInput;  // the number input by the user
>                          int square;     // the userInput, multiplied by itself

>                          System.out.print("Please type a number: ");
>                          userInput = TextIO.getInt();
>                          square = userInput * userInput;
>                          System.out.print("The square of that number is ");
>                          System.out.println(square);

>                       } // end of main()

>                     } //end of class PrintSquare

> Here's an applet that simulates this program. When you run the program, it will display the message "Please type a number: " and will pause until you type a response. (If the applet does not respond to your typing, you might have to click on it to activate it. In some browsers, you might also need to leave the mouse cursor inside the applet for it to recognize your typing.)

> (Applet "PrintSquareConsole" would be displayed here
> if Java were available.)

> The `TextIO` class contains static member subroutines `TextIO.put` and `TextIO.putln` that can be used in the same way as `System.out.print` and `System.out.println`. For example, although there is no particular advantage in doing so in this case, you could replace the two lines

>                          System.out.print("The square of that number is ");
>                          System.out.println(square);

> with

>                          TextIO.put("The square of that number is ");
>                          TextIO.putln(square);

> For the next few chapters, I will use `TextIO` for input in all my examples, and I will often use it for output. Keep in mind that `TextIO` can only be used in a program if `TextIO.class` is available to that program. It is not built into Java, as the `System` class is.

> Let's look a little more closely at the built-in output subroutines `System.out.print` and `System.out.println`. Each of these subroutines can be used with one parameter, where the parameter can be any value of type `byte`, `short`, `int`, `long`, `float`, `double`, `char`, `boolean`, or `String`. (These are the eight primitive types plus the type `String`.) That is, you can say "`System.out.print(x);`" or "`System.out.println(x)`;", where `x` is any expression whose value is of one of these types. The expression can be a constant, a variable, or even something more complicated such as `2*distance*time`. In fact, there are actually several different subroutines to handle the different parameter types. There is one `System.out.print` for printing values of type `double`, one for values of type `int`, another for values of type `String`, and so on. These subroutines can have the same name since the computer can tell which one you mean in a given subroutine call statement, depending on the type of parameter that you supply. Having several subroutines of the same name that differ in the types of their parameters is called overloading. Many programming languages do not permit overloading, but it is common in Java programs.

> The difference between `System.out.print` and `System.out.println` is that `System.out.println` outputs a carriage return after it outputs the specified parameter value. There is a version of `System.out.println` that has no parameters. This version simply outputs a carriage return, and nothing else. Of course, a subroutine call statement for this version of the program looks like "`System.out.println();`", with empty parentheses. Note that "`System.out.println(x)`;" is exactly equivalent to "`System.out.print(x); System.out.println();`". (There is no version of `System.out.print` without parameters. Do you see why?)

> As mentioned above, the `TextIO` subroutines `TextIO.put` and `TextIO.putln` can be used as replacements for `System.out.print` and `System.out.println`. However, `TextIO` goes beyond `System.out` by providing additional, two-parameter versions of `put` and `putln`. You can use subroutine call statements of the form "`TextIO.put(x,n)`;" and "`TextIO.putln(x,n);`", where the second parameter, `n`, is an integer-valued expression. The idea is that `n` is the number of characters that you want to output. If `x` takes up fewer than `n` characters, then the computer will add some spaces at the beginning to bring the total up to `n`. (If `x` already takes up more than `n` characters, the computer will just print out more characters than you ask for.) This feature is useful, for example, when you are trying to output neat columns of numbers, and you know just how many characters you need in each column.

> The `TextIO` class is a little more versatile at doing output than is `System.out`. However, it's input for which we really need it.

> With `TextIO`, input is done using functions. For example, `TextIO.getInt()`, which was discussed above, makes the user type in a value of type `int` and returns that input value so that you can use it in your program. `TextIO` includes several functions for reading different types of input values. Here are examples of using each of them:

>              b = TextIO.getByte();    // value read is a byte
>              i = TextIO.getShort();   // value read is a short
>              j = TextIO.getInt();     // value read is an int
>              k = TextIO.getLong();    // value read is a long
>              x = TextIO.getFloat();   // value read is a float
>              y = TextIO.getDouble();  // value read is a double
>              a = TextIO.getBoolean(); // value read is a boolean
>              c = TextIO.getChar();    // value read is a char
>              w = TextIO.getWord();    // value read is a String
>              s = TextIO.getln();      // value read is a String

> For these statements to be legal, the variables on the left side of each assignment statement must be of the same type as that returned by the function on the right side.

> When you call one of these functions, you are guaranteed that it will return a legal value of the correct type. If the user types in an illegal value as input -- for example, if you ask for a `byte` and the user types in a number that is outside the legal range of -128 to 127 -- then the computer will ask the user to re-enter the value, and your program never sees the first, illegal value that the user entered.

> You'll notice that there are two input functions that return Strings. The first, `getWord()`, returns a string consisting of non-blank characters only. When it is called, it skips over any spaces and carriage returns typed in by the user. Then it reads non-blank characters until it gets to the next space or carriage return. It returns a `String` consisting of all the non-blank characters that it has read. The second input function, `getln()`, simply returns a string consisting of all the characters typed in by the user, including spaces, up to the next carriage return. It gets an entire line of input text. The carriage return itself is not returned as part of the input string, but it is read and discarded by the computer. Note that the String returned by this function might be the empty string, `""`, which contains no characters at all.

> All the other input functions listed -- `getByte()`, `getShort()`, `getInt()`, `getLong()`, `getFloat()`, `getDouble()`, `getBoolean()`, and `getChar()` -- behave like `getWord()`. That is, they will skip past any blanks and carriage returns in the input before reading a value. However, they will not skip past other characters. If you try to read two `ints` and the user types "2,3", the computer will read the first number correctly, but when it tries to read the second number, it will see the comma. It will regard this as an error and will force the user to retype the number. If you want to input several numbers from one line, you should make sure that the user knows to separate them with spaces, not commas. Alternatively, if you want to require a comma between the numbers, use `getChar()` to read the comma before reading the second number.

> There is another character input function, `TextIO.getAnyChar()`, which does not skip past blanks or carriage returns. It simply reads and returns the next character typed by the user. This could be any character, including a space or a carriage return. If the user typed a carriage return, then the `char` returned by `getChar()` is the special linefeed character '\n'. There is also a function, `TextIO.peek()`, that let's you look ahead at the next character in the input without actually reading it. After you "peek" at the next character, it will still be there when you read the next item from input. This allows you to look ahead and see what's coming up in the input, so that you can take different actions depending on what's there.

> The semantics of input is much more complicated than the semantics of output. The first time the program tries to read input from the user, the computer will wait while the user types in an entire line of input. `TextIO` stores that line in a chunk of internal memory called the input buffer. Input is actually read from the buffer, not directly from the user's typing. The user only gets to type when the buffer is empty. This lets you read several numbers from one line of input. However, if you only want to read in one number and the user types in extra stuff on the line, then you could be in trouble. The extra stuff will still be there the next time you try to read something from input. (The symptom of this trouble is that the computer doesn't pause where you think it should to let the user type something in. The computer had stuff left over in the input buffer from the previous line that the user typed.) To help you avoid this, there are versions of the `TextIO` input functions that read a data value and then discard any leftover stuff on the same line:

>              b = TextIO.getlnByte();    // value read is a byte
>              i = TextIO.getlnShort();   // value read is a short
>              j = TextIO.getlnInt();     // value read is an int
>              k = TextIO.getlnLong();    // value read is a long
>              x = TextIO.getlnFloat();   // value read is a float
>              y = TextIO.getlnDouble();  // value read is a double
>              a = TextIO.getlnBoolean(); // value read is a boolean
>              c = TextIO.getlnChar();    // value read is a char
>              w = TextIO.getlnWord();    // value read is a String

> Note that calling `getlnDouble()`, for example, is equivalent to first calling `getDouble()` and then calling `getln()` to read any remaining data on the same line, including the end-of-line character itself. I strongly advise you to use the "getln" versions of the input routines, rather than the "get" versions, unless you really want to read several items from the same line of input.

> You might be wondering why there are only two output routines, `put` and `putln`, which can output data values of any type, while there is a separate input routine for each data type. As noted above, in reality there are many `put` and `putln` routines. The computer can tell them apart based on the type of the parameter that you provide. However, the input routines don't have parameters, so the different input routines can only be distinguished by having different names.

> Using `TextIO` for input and output, we can now improve the program from Section 2 for computing the value of an investment. We can have the user type in the initial value of the investment and the interest rate. The result is a much more useful program -- for one thing, it makes sense to run more than once!

>              public class Interest2 {

>                 /*
>                    This class implements a simple program that
>                    will compute the amount of interest that is
>                    earned on an investment over a period of
>                    one year.  The initial amount of the investment
>                    and the interest rate are input by the user.
>                    The value of the investment at the end of the
>                    year is output.  The rate must be input as a
>                    decimal, not a percentage (for example, 0.05,
>                    rather than 5).
>                 */

>                 public static void main(String[] args) {

>                     double principal;  // the value of the investment
>                     double rate;       // the annual interest rate
>                     double interest;   // the interest earned during the year

>                     TextIO.put("Enter the initial investment: ");
>                     principal = TextIO.getlnDouble();

>                     TextIO.put("Enter the annual interest rate: ");
>                     rate = TextIO.getlnDouble();

>                     interest = principal * rate;   // compute this year's interest
>                     principal = principal + interest;     // add it to principal

>                     TextIO.put("The value of the investment after one year is $");
>                     TextIO.putln(principal);

>                 } // end of main()

>              } // end of class Interest2

> Try out an equivalent applet here. (If the applet does not respond to your typing, you might have to click on it to activate it.)

> (Applet "Interest2Console" would be displayed here
> if Java were available.)

> By the way, the applets on this page don't actually use `TextIO`. The `TextIO` class is only for use in programs, not applets. For applets, I have written a separate class that provides similar input/output capabilities in a Graphical User Interface program.

[ Next Section | Previous Section | Chapter Index | Main Index ]