In this lab, you will learn how to use exceptions to handle unexpected or erroneous input gracefully. For the assignment, you will write a program that parses integer values given by the user as input. That is, given a sequence of characters, your program will either (1) identify the string as representing an integer and store that value as an
int, or (2) identify that the string does not represent an integer, and send an appropriate warning to the user. In case (2), the program should return to a “safe” state and continue to operate as expected despite the “bad” input given by the user.
Note. To get going with the lab, here are some extra resources for exception handling:
I recommend writing a version of the program that does catch exceptions first, then modifing your program to handle exceptions. I also suggest working through the Handling Exceptions notes before impelementing the exception handling part of the program.
Here is a sample interaction with the completed program:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 Enter a number (-1 to exit): 1 x = 1 Enter a number (-1 to exit): 142 x = 142 Enter a number (-1 to exit): -452 x = -452 Enter a number (-1 to exit): 1c34 Could not read integer. InvalidIntegerException: Non-numerical character 'c' encountered. Enter a number (-1 to exit): 14.3 Could not read integer. InvalidIntegerException: Non-numerical character '.' encountered. Enter a number (-1 to exit): -34.2 Could not read integer. InvalidIntegerException: Non-numerical character '.' encountered. Enter a number (-1 to exit): 1 2 3 4 5 x = 1 Enter a number (-1 to exit): x = 2 Enter a number (-1 to exit): x = 3 Enter a number (-1 to exit): x = 4 Enter a number (-1 to exit): x = 5 Enter a number (-1 to exit): -1 x = -1 Goodbye!
In particular, the “expected” inputs (i.e., strings of characters representing integers) are handled as expected. “Unexpected” inputs result in a warning being printed the user, but the program does not crash. Instead, the program returns to a state where it can read the next input from the user.
To get started, download the following files, linked to below:
There are two things you must complete in the code above:
Parser.java, write the method
int readInt(). The method should read characters from the
InputStream in(an instance variable for the
Parserclass). Specifically, your method should read the successive characters from
inuntil the next whitespace character or end of stream is encountered (The method
Character.isWhitespace(char ch)will probably be helpful here). If those characters constitute an integer—i.e., are all digits
9, possibly starting with the
readInt()should return the
intwhose decimal representation corresponds to these characters. If a non-numerical character is encountered,
readInt()should do the following.
- Continue reading from
inuntil the next whitespace character is read or the end of the stream is reached.
- Throw an
InvalidIntegerExceptionwith a message indicating the first non-numerical character encountered in
- Continue reading from
ParserTester.java, modify the main loop so that the program also catches any
Parser. When an
InvalidIntegerExceptionis caught, the program should print the message
Could not read integer.to the screen, followed by the details of the caught exception. Note that an
InvalidIntegerExceptionshould not break out of the main loop in the program—after an
InvalidIntegerException, the user should be able to continue entering more values.
InputStream offers only basic operations for reading input. Specifically, you will need to use the
read() method to access each character from
in individually. See the
InputStream documentation for more info. Note that
read() throws an exception, so you must update the declaration of
readInt() to deal with this exception as well as the
InvalidIntegerException you define.
As indicated in the
InputStream documentation, the
read() method returns an
int whose value is
-1 if the end of the stream is reached. Otherwise, the returned value is between 0 and 255 (inclusive), and represents the next byte stored in the stream. Each byte represents a single character in the stream. For ASCII text (i.e., the text encoding used for console applications), you can see the correspondence between
int) values and their
char equivalents on this page. From the chart, we can see that, for example, casting the character
' as an
int will store a value of 87.
1 2 int capitalA = (int) 'A'; // stores value 65 int lowerCaseB = (int) 'b'; // stores value 98
Thankfully, you don’t need to know the conversion from
int explicitly to figure out the value of a digit associated to a char. It is enough to know that the characters
9 appear sequentially in the ASCII code. Thus, we can use the following trick to get an int whose value is the digit stored in a char
1 int digit = (int) ch - (int) '0';
For example if
ch stores the character
4, the value of
digit will be
4 after executing the line above. This pattern will be helpful to get the numerical value associated to a digit read from
in. You can also test that
ch represents a digit by checking if
(int) 0 <= (int) ch and
(int) ch <= (int) 9.
A note on style
In order to refer to refer to a fixed
char value, you should always use the literal character in your code rather than its ASCII (integer) value. For example:
1 2 char c = 'A'; // GOOD: refer to the literal char char d = 65; // BAD: never do this
Your program must implement the logic to parse an
int from a sequence of
chars. In particular, you may not use the
Integer.parseInt(...) method, or any similar method that handles the parsing for you.
What to submit
Submit all code needed to run your program (
ParserTester.java) to the Moodle site by Friday, March 26th, 11:59 AoE. Additionally, please fill out the survey linked to from the Moodle submission site.
The lab will be graded on a 3 point scale as follows:
- 3 Everything compiles and runs as specified in this document; code is fairly readable and contains comments briefly describing the main functionality of methods defined/larger chunks of code.
- 2 The program produces more-or-less correct output, but is sloppy/hard to read; comments may be there, but are not helpful.
- 1 Program compiles, but is far from producing the expected output and/or does not run as specified; comments unhelpful or absent.
- 0 Program doesn’t compile or outputs garbage; no comments explaining why.
Additionally, extra credit will be awarded for early submissions (up to 4 days early) as specified in the course syllabus.
Write a program that uses the
InputStream and exception handling to validate other types of input. For example, you could write a password validator that reads a stream of characters (ending with whitespace) and determines if the text is a strong password. Here a strong password should:
- be at least 8 characters in length;
- contain at least one capital and one lower-case letter;
- contain at least one numerical character;
- contain at least one “special” character (not a letter or number).