• 沒有找到結果。

Syntax 3.3 : Cast

3.8 Reading Input

You may prefer the numbers to be printed with two digits after the decimal point, like this:

Total: $3.50 Tax: $0.30

You can achieve this with the NumberFormat class in the java.text package. First, you must use the static method getNumberInstance to obtain a NumberFormat object.

Then you set the maximum number of fraction digits to 2:

NumberFormat formatter =

NumberFormat.getNumberInstance();

formatter.setMaximumFractionDigits(2);

Then the numbers are rounded to two digits. For example, 0.2875 will be converted to the string "0.29". On the other hand, 0.2975 will be converted to "0.3", not "0.30". If you want trailing zeroes, you also have to set the minimum number of fraction digits to 2:

formatter.setMinimumFractionDigits(2);

Then you use the format method of that object. The result is a string that you can print.

formatter.format(tax)

returns the string "0.30". The statement

System.out.println("Tax: $" + formatter.format(tax));

rounds the value of tax to two digits after the decimal point and prints: Tax: $0.30. The “number instance” formatter is useful because it lets you print numbers with as many fraction digits as desired. If you just want to print a currency value, the getCurrencyInstance method of the NumberFormat class produces a more conve-nient formatter. The “currency instance” formatter generates currency value strings, with the local currency symbol (such as $ in the United States) and the appropriate number of digits after the decimal point (for example, two digits in the United States).

NumberFormat formatter = NumberFormat.getCurrencyInstance();

System.out.print(formatter.format(tax));

// prints "$0.30"

The Java programs that you have constructed so far have constructed objects, called methods, printed results, and exited. They were not interactive and took no user input.

In this section, you will learn one method for reading user input.

The JOptionPane class has a static method showInputDialog that displays an input dialog (see Figure 7). The user can type any string into the input field and click the “OK” button. Then the show-InputDialog method returns the string that the user entered. You should capture the user input in a string variable. For example, String input =

JOptionPane.showInputDialog("How many nickels do you have?");























Often you want the input as a number, not a string. Use the Integer.parseInt and Double.parseDouble methods to convert the string to a number:

int count = Integer.parseInt(input);

If the user doesn’t type in a number, then the parseInt method throws an exception. An exception is a way for a method to indicate an error condition. You will see in Chapter 15 how to handle exceptions. Until then, we will simply rely on the default mechanism for exception handling. That mechanism terminates the program with an error message.

Exception in thread "main"

java.lang.NumberFormatException: x

at java.lang.Integer.parseInt(Unknown Source) at java.lang.Integer.parseInt(Unknown Source) at InputTest.main(InputTest.java:10)

That doesn’t make your programs very user-friendly. You will simply have to wait until Chapter 15 to make your programs bulletproof. In the meantime, you should assume that the user is cooperative and types in an actual number when you prompt for one. Since the users of your first programs are likely to be just your-self, your instructor, and your grader, that should not be a problem.

Finally, whenever you call JOptionPane.showInputDialog in your programs, you need to add a line

System.exit(0)

to the end of your main method. The showInputDialog method starts a user interface thread to handle user input. When the main method reaches the end, that thread is still running, and your program won’t exit automatically. (See Chapter 20 for more informa-tion on threads.) To force the program to exit, you need to call the exit method of the System class. The parameter of the exit method is the status code of the program. A code of 0 denotes successful completion; you can use nonzero status codes to denote var-ious error conditions.

Here is an example of a test class that takes user input. This class tests the Purse class and lets the user supply the numbers of nickels, dimes, and quarters.

File InputTest.java

1 import javax.swing.JOptionPane;

2 3 /**

4 This program tests input from an input dialog.

F i g u r e 7

An Input Dialog

You must call System.

exit(0) to exit a program that has a graphical user interface.

5 */

6 public class InputTest 7 {

8 public static void main(String[] args) 9 {

10 Purse myPurse = new Purse();

11

12 String input = JOptionPane.showInputDialog(

13 "How many nickels do you have?");

14 int count = Integer.parseInt(input);

15 myPurse.addNickels(count);

16

17 input = JOptionPane.showInputDialog(

18 "How many dimes do you have?");

19 count = Integer.parseInt(input);

20 myPurse.addDimes(count);

21

22 input = JOptionPane.showInputDialog(

23 "How many quarters do you have?");

24 count = Integer.parseInt(input);

25 myPurse.addQuarters(count);

26

27 double totalValue = myPurse.getTotal();

28 System.out.println("The total is " + totalValue);

29

30 System.exit(0);

31 } 32 }

Admittedly, the program is not very elegant. It pops up three dialog boxes to collect input and then displays the output in the console window. You will learn in Chapter 12 how to write programs with more sophisticated graphical user interfaces.

Reading Exception Reports

You will often have programs that terminate and display an error message such as Exception in thread "main" java.lang.NumberFormatException: x at java.lang.Integer.parseInt(Unknown Source)

at java.lang.Integer.parseInt(Unknown Source) at InputTest.main(InputTest.java:10)

An amazing number of students simply give up at that point, saying “it didn’t work”, or

“my program died”, without ever reading the error message. Admittedly, the format of the exception report is not very friendly. But it is actually easy to decipher it.

Productivity Hint 3.3









When you have a close look at the error message, you will notice two pieces of useful information:

1. The name of the exception, such as NumberFormatException

2. The line number of the code that contained the statement that caused the excep-tion, such as InputTest.java:10

The name of the exception is always in the first line of the report, and it ends in Exception. If you get a NumberFormatException, then there was a problem with the format of some number. That is useful information.

The line number of the offending code is a little harder to determine. The exception report contains the entire stack trace—that is, the names of all methods that were pending when the exception hit. The first line of the stack trace is the method that actually gener-ated the exception. The last line of the stack trace is a line in main. Often, the exception was thrown by a method that is in the standard library. Look for the first line in your code that appears in the exception report. For example, skip the lines that refer to

java.lang.Integer.parseInt(Unknown Source).

Once you have the line number in your code, open up the file, go to that line, and look at it! In the great majority of cases, knowing the name of the exception and the line that caused it makes it completely obvious what went wrong, and you can easily fix your error.

Reading Console Input

You just saw how to read input from an input dialog. Admittedly, it is a bit strange to have dialogs pop up for every input. Some programmers prefer to read the input from the console window. Console input has one great advantage. As you will see in Chapter 6, you can put all your input strings into a file and redirect the console input to read from a file. That’s a great help for program testing. However, console input is somewhat cum-bersome to program. This note explains the details.

Console input reads from the System.in object. However, unlike System.out, which was ready-made for printing numbers and strings, System.in can only read bytes.

Keyboard input consists of characters. To get a reader for characters, you have to turn System.in into an InputStreamReader object, like this:

InputStreamReader reader =

newInputStreamReader(System.in);

An input stream reader can read characters, but it can’t read a whole string at a time. That makes it pretty inconvenient—you wouldn’t want to piece together every input line from its individual characters.

To overcome this limitation, you can turn an input stream reader into a BufferedReader object:

BufferedReader console = new BufferedReader(reader);















Advanced Topic 3.6















Wrap System.in inside a BufferedReader to read input from the console window.

If you like, you can combine the two constructors:

BufferedReader console = new BufferedReader(

new InputStreamReader(System.in));

Now you use the readLine method to read an input line, like this:

System.out.println(

"How many nickels do you have?");

String input = console.readLine();

int count = Integer.parseInt(input);

There is one remaining problem. When there is a problem with read-ing input, the readLine method generates an exception, just as the parseInt method does when you give it a string that isn’t an integer.

However, the readLine method generates an IOException, which is a checked exception, a more severe kind of exception than the Num-berFormatException that the parseInt method generates. The Java compiler insists that you take one of two steps when you call a method that can throw a checked exception.

1. Handle the exception. You will see how to do that in Chapter 15

2. Acknowledge that you are not handling the exception. Then you have to indicate that your method can cause a checked exception because it calls another method that can cause that exception. You do that by tagging your method with a throws specifier, like this:

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

public void readInput(BufferedReader reader) throws IOException There is no shame associated with acknowledging that your method might throw a checked exception—it is just “truth in advertising”. Of course, in a professional program, you do need to handle all exceptions somewhere, and the main method won’t throw any exceptions. You’ll have to wait for Chapter 15 for the details.

Following this note is another version of the test program for the Purse class, this time reading input from the console. Figure 8 shows a typical program run.

File ConsoleInputTest.java

1 import java.io.BufferedReader;

2 import java.io.InputStreamReader;

3 import java.io.IOException;

4 5 /**

6 This program tests input from a console window.

7 */





















When calling the readLine method of the BufferedReader class, you must tag the calling methods with throws IOException.

8 public class ConsoleInputTest 9 {

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

12 Purse myPurse = new Purse();

13 14

15 BufferedReader console = new BufferedReader(

16 new InputStreamReader(System.in));

17 System.out.println(

18 "How many nickels do you have?");

19 String input = console.readLine();

20 int count = Integer.parseInt(input);

21 myPurse.addNickels(count);

22

23 System.out.println("How many dimes do you have?");

24 input = console.readLine();

25 count = Integer.parseInt(input);

26 myPurse.addDimes(count);

27

28 System.out.println(

29 "How many quarters do you have?");

30 input = console.readLine();

31 count = Integer.parseInt(input);

32 myPurse.addQuarters(count);

33

34 double totalValue = myPurse.getTotal();

35 System.out.println("The total is " + totalValue);

F i g u r e 8

Reading Input from the Console

36

37 System.exit(0);

38 } 39 }

Strings are composed of individual characters. Characters are values of the char type. A variable of type char can hold a single character.

Character constants look like string constants, except that char-acter constants are delimited by single quotes: 'H' is a character,

"H" is a string containing a single character. You can use escape sequences (see Advanced Topic 1.1) inside character constants. For example, '\n' is the newline character, and '\u00E9' is the char-acter é. You can find the values of the charchar-acter constants that are used in Western European languages in Appendix A6.

Characters have numeric values. For example, if you look at Appendix A6, you can see that the character 'H' is actually encoded as the number 72.

The charAt method of the String class returns a character from a string. As with the substring method, the positions in the string are counted starting at 0. For exam-ple, the statement

String greeting = "Hello";

char ch = greeting.charAt(0);

sets ch to the character 'H'.

International Alphabets

The English alphabet is pretty simple: upper- and lowercase a to z. Other European lan-guages have accent marks and special characters. For example, German has three umlaut characters (ä, ö, ü) and a double-s character (ß). These are not optional frills; you couldn’t write a page of German text without using these characters a few times. German com-puter keyboards have keys for these characters (see Figure 9).

This poses a problem for computer users and designers. The American standard character encoding (called ASCII, for American Standard Code for Information Interchange) specifies 128 codes: 52 upper- and lowercase characters, 10 digits, 32 typographical symbols, and 34 control characters (such as space, newline, and 32 oth-ers for controlling printoth-ers and other devices). The umlaut and double-s are not among them. Some German data processing systems replace seldom-used ASCII characters with German letters: [ \ ] { | } ~ are replaced with Ä Ö Ü ä ö ü ß.

相關文件