public class SavitchIn
1: import java.io.*;
2: import java.util.*;
3:
4: /**
5: Class for simple console input.
6: A class designed primarily for simple keyboard input of the
7: form one input value per line. If the user enters an improper
8: input, i.e., an input of the wrong type or a blank line, then
9: the user is prompted to reenter the input and given a brief
10: explanation of what is required. Also includes some additional
11: methods to input single numbers, words, and characters, without
12: going to the next line.
13: */
14: public class SavitchIn
15: {
16: /**
17: Reads a line of text and returns that line as a String
18: value. The end of a line must be indicated either by a
19: new-line character '\n' or by a carriage return '\r'
20: followed by a new-line character '\n'. (Almost all systems
21: do this automatically. So you need not worry about this
22: detail.) Neither the '\n', nor the '\r' if present, are
23: part of the string returned. This will read the rest of a
24: line if the line is already partially read.
25: */
26: public static String readLine( )
27: {
28: char nextChar;
29: String result = "";
30: boolean done = false;
31:
32: while (!done)
33: {
34: nextChar = readChar( );
35: if (nextChar == '\n')
36: done = true;
37: else if (nextChar == '\r')
38: {
39: //Do nothing.
40: //Next loop iteration will detect '\n'.
41: }
42: else
43: result = result + nextChar;
44: }
45:
46: return result;
47: }
48:
49: /**
50: Reads the first string of nonwhitespace characters on
51: a line and returns that string. The rest of the line
52: is discarded. If the line contains only whitespace,
53: the user is asked to reenter the line.
54: */
55: public static String readLineWord( )
56: {
57: String inputString = null,
58: result = null;
59: boolean done = false;
60:
61: while(!done)
62: {
63: inputString = readLine( );
64: StringTokenizer wordSource =
65: new StringTokenizer(inputString);
66: if (wordSource.hasMoreTokens( ))
67: {
68: result = wordSource.nextToken( );
69: done = true;
70: }
71: else
72: {
73: System.out.println(
74: "Your input is not correct. Your input must");
75: System.out.println(
76: "contain at least one nonwhitespace character.");
77: System.out.println(
78: "Please try again. Enter input:");
79: }
80: }
81:
82: return result;
83: }
84:
85: /**
86: Precondition: The user has entered a number of type int
87: on a line by itself, except that there may be
88: whitespace before and/or after the number.
89: Action: Reads and returns the number as a value of type
90: int. The rest of the line is discarded. If the input is
91: not entered correctly, then in most cases, the user will
92: be asked to reenter the input. In particular, this
93: applies to incorrect number formats and blank lines.
94: */
95: public static int readLineInt( )
96: {
97: String inputString = null;
98: int number = -9999;//To keep the compiler happy.
99: //Designed to look like a garbage value.
100: boolean done = false;
101:
102: while (! done)
103: {
104: try
105: {
106: inputString = readLine( );
107: inputString = inputString.trim( );
108: number = Integer.parseInt(inputString);
109: done = true;
110: }
111: catch (NumberFormatException e)
112: {
113: System.out.println(
114: "Your input number is not correct.");
115: System.out.println(
116: "Your input number must be");
117: System.out.println(
118: "a whole number written as an");
119: System.out.println(
120: "ordinary numeral, such as 42");
121: System.out.println("Minus signs are OK,"
122: + "but do not use a plus sign.");
123: System.out.println("Please try again.");
124: System.out.println("Enter a whole number:");
125: }
126: }
127:
128: return number;
129: }
130:
131: /**
132: Precondition: The user has entered a number of type long
133: on a line by itself, except that there may be whitespace
134: before and/or after the number.
135: Action: Reads and returns the number as a value of type
136: long. The rest of the line is discarded. If the input is
137: not entered correctly, then in most cases, the user will
138: be asked to reenter the input. In particular, this
139: applies to incorrect number formats and blank lines.
140: */
141: public static long readLineLong( )
142: {
143: String inputString = null;
144: long number = -9999;//To keep the compiler happy.
145: //Designed to look like a garbage value.
146: boolean done = false;
147:
148: while (! done)
149: {
150: try
151: {
152: inputString = readLine( );
153: inputString = inputString.trim( );
154: number = Long.parseLong(inputString);
155: done = true;
156: }
157: catch (NumberFormatException e)
158: {
159: System.out.println(
160: "Your input number is not correct.");
161: System.out.println(
162: "Your input number must be");
163: System.out.println(
164: "a whole number written as an");
165: System.out.println(
166: "ordinary numeral, such as 42");
167: System.out.println("Minus signs are OK,"
168: + "but do not use a plus sign.");
169: System.out.println("Please try again.");
170: System.out.println("Enter a whole number:");
171: }
172: }
173:
174: return number;
175: }
176:
177: /**
178: Precondition: The user has entered a number of type
179: double on a line by itself, except that there may be
180: whitespace before and/or after the number.
181: Action: Reads and returns the number as a value of type
182: double. The rest of the line is discarded. If the input
183: is not entered correctly, then in most cases, the user
184: will be asked to reenter the input. In particular, this
185: applies to incorrect number formats and blank lines.
186: */
187: public static double readLineDouble( )
188: {
189: String inputString = null;
190: double number = -9999;//To keep the compiler happy.
191: //Designed to look like a garbage value.
192: boolean done = false;
193:
194: while (! done)
195: {
196: try
197: {
198: inputString = readLine( );
199: inputString = inputString.trim( );
200: number = Double.parseDouble(inputString);
201: done = true;
202: }
203: catch (NumberFormatException e)
204: {
205: System.out.println(
206: "Your input number is not correct.");
207: System.out.println(
208: "Your input number must be");
209: System.out.println(
210: "an ordinary number either with");
211: System.out.println(
212: "or without a decimal point,");
213: System.out.println("such as 42 or 9.99");
214: System.out.println("Please try again.");
215: System.out.println("Enter the number:");
216: }
217: }
218:
219: return number;
220: }
221:
222: /**
223: Precondition: The user has entered a number of type float
224: on a line by itself, except that there may be whitespace
225: before and/or after the number.
226: Action: Reads and returns the number as a value of type
227: float. The rest of the line is discarded. If the input is
228: not entered correctly, then in most cases, the user will
229: be asked to reenter the input. In particular,
230: this applies to incorrect number formats and blank lines.
231: */
232: public static float readLineFloat( )
233: {
234: String inputString = null;
235: float number = -9999;//To keep the compiler happy.
236: //Designed to look like a garbage value.
237: boolean done = false;
238:
239: while (! done)
240: {
241: try
242: {
243: inputString = readLine( );
244: inputString = inputString.trim( );
245: number = Float.parseFloat(inputString);
246: done = true;
247: }
248: catch (NumberFormatException e)
249: {
250: System.out.println(
251: "Your input number is not correct.");
252: System.out.println(
253: "Your input number must be");
254: System.out.println(
255: "an ordinary number either with");
256: System.out.println(
257: "or without a decimal point,");
258: System.out.println("such as 42 or 9.99");
259: System.out.println("Please try again.");
260: System.out.println("Enter the number:");
261: }
262: }
263:
264: return number;
265: }
266:
267: /**
268: Reads the first nonwhitespace character on a line and
269: returns that character. The rest of the line is
270: discarded. If the line contains only whitespace, the
271: user is asked to reenter the line.
272: */
273: public static char readLineNonwhiteChar( )
274: {
275: boolean done = false;
276: String inputString = null;
277: char nonWhite = ' ';//To keep the compiler happy.
278:
279: while (! done)
280: {
281: inputString = readLine( );
282: inputString = inputString.trim( );
283: if (inputString.length( ) == 0)
284: {
285: System.out.println(
286: "Your input is not correct.");
287: System.out.println(
288: "Your input must contain at");
289: System.out.println(
290: "least one nonwhitespace character.");
291: System.out.println("Please try again.");
292: System.out.println("Enter input:");
293: }
294: else
295: {
296: nonWhite = (inputString.charAt(0));
297: done = true;
298: }
299: }
300:
301: return nonWhite;
302: }
303:
304: /**
305: Input should consist of a single word on a line, possibly
306: surrounded by whitespace. The line is read and discarded.
307: If the input word is "true" or "t", then true is returned.
308: If the input word is "false" or "f", then false is
309: returned. Uppercase and lowercase letters are considered
310: equal. If the user enters anything else (e.g., multiple
311: words or different words), the user is asked
312: to reenter the input.
313: */
314: public static boolean readLineBoolean( )
315: {
316: boolean done = false;
317: String inputString = null;
318: boolean result = false;//To keep the compiler happy.
319:
320: while (! done)
321: {
322: inputString = readLine( );
323: inputString = inputString.trim( );
324: if (inputString.equalsIgnoreCase("true")
325: || inputString.equalsIgnoreCase("t"))
326: {
327: result = true;
328: done = true;
329: }
330: else if (inputString.equalsIgnoreCase("false")
331: || inputString.equalsIgnoreCase("f"))
332: {
333: result = false;
334: done = true;
335: }
336: else
337: {
338: System.out.println(
339: "Your input is not correct.");
340: System.out.println("Your input must be");
341: System.out.println("one of the following:");
342: System.out.println("the word true,");
343: System.out.println("the word false,");
344: System.out.println("the letter T,");
345: System.out.println("or the letter F.");
346: System.out.println(
347: "You may use either upper-");
348: System.out.println("or lowercase letters.");
349: System.out.println("Please try again.");
350: System.out.println("Enter input:");
351: }
352: }
353:
354: return result;
355: }
356:
357: /**
358: Reads the next input character and returns that character.
359: The next read takes place on the same line where this
360: one left off.
361: */
362: public static char readChar( )
363: {
364: int charAsInt = -1; //To keep the compiler happy.
365: try
366: {
367: charAsInt = System.in.read( );
368: }
369: catch(IOException e)
370: {
371: System.out.println(e.getMessage( ));
372: System.out.println("Fatal error. Ending program.");
373: System.exit(0);
374: }
375:
376: return (char)charAsInt;
377: }
378:
379: /**
380: Reads the next nonwhitespace input character and returns
381: that character. The next read takes place immediately
382: after the character read.
383: */
384: public static char readNonwhiteChar( )
385: {
386: char next;
387:
388: next = readChar( );
389: while (Character.isWhitespace(next))
390: next = readChar( );
391:
392: return next;
393: }
394:
395:
396: /**
397: The following methods are not used in the text, except
398: for a brief reference in Chapter 2. No program code uses
399: them. However, some programmers may want to use them.
400: */
401:
402:
403: /**
404: Precondition: The next input in the stream consists of
405: an int value, possibly preceded by whitespace, but
406: definitely followed by whitespace.
407: Action: Reads the first string of nonwhitespace characters
408: and returns the int value it represents. Discards the
409: first whitespace character after the word. The next read
410: takes place immediately after the discarded whitespace.
411: In particular, if the word is at the end of a line, the
412: next read will take place starting on the next line.
413: If the next word does not represent an int value,
414: a NumberFormatException is thrown.
415: */
416: public static int readInt( ) throws NumberFormatException
417: {
418: String inputString = null;
419: inputString = readWord( );
420: return Integer.parseInt(inputString);
421: }
422:
423: /**
424: Precondition: The next input consists of a long value,
425: possibly preceded by whitespace, but definitely
426: followed by whitespace.
427: Action: Reads the first string of nonwhitespace characters
428: and returns the long value it represents. Discards the
429: first whitespace character after the string read. The
430: next read takes place immediately after the discarded
431: whitespace. In particular, if the string read is at the
432: end of a line, the next read will take place starting on
433: the next line. If the next word does not represent a long
434: value, a NumberFormatException is thrown.
435: */
436: public static long readLong( )
437: throws NumberFormatException
438: {
439: String inputString = null;
440: inputString = readWord( );
441: return Long.parseLong(inputString);
442: }
443:
444: /**
445: Precondition: The next input consists of a double value,
446: possibly preceded by whitespace, but definitely
447: followed by whitespace.
448: Action: Reads the first string of nonwhitespace characters
449: and returns the double value it represents. Discards the
450: first whitespace character after the string read. The
451: next read takes place immediately after the discarded
452: whitespace. In particular, if the string read is at the
453: end of a line, the next read will take place starting on
454: the next line. If the next word does not represent a
455: double value, a NumberFormatException is thrown.
456: */
457: public static double readDouble( )
458: throws NumberFormatException
459: {
460: String inputString = null;
461: inputString = readWord( );
462: return Double.parseDouble(inputString);
463: }
464:
465: /**
466: Precondition: The next input consists of a float value,
467: possibly preceded by whitespace, but definitely
468: followed by whitespace.
469: Action: Reads the first string of nonwhitespace characters
470: and returns the float value it represents. Discards the
471: first whitespace character after the string read. The
472: next read takes place immediately after the discarded
473: whitespace. In particular, if the string read is at the
474: end of a line, the next read will take place starting on
475: the next line. If the next word does not represent
476: a float value, a NumberFormatException is thrown.
477: */
478: public static float readFloat( )
479: throws NumberFormatException
480: {
481: String inputString = null;
482: inputString = readWord( );
483: return Float.parseFloat(inputString);
484: }
485:
486: /**
487: Reads the first string of nonwhitespace characters and
488: returns that string. Discards the first whitespace
489: character after the string read. The next read takes
490: place immediately after the discarded whitespace. In
491: particular, if the string read is at the end of a line,
492: the next read will take place starting on the next line.
493: Note that if it receives blank lines, it will wait until
494: it gets a nonwhitespace character.
495: */
496: public static String readWord( )
497: {
498: String result = "";
499: char next;
500:
501: next = readChar( );
502: while (Character.isWhitespace(next))
503: next = readChar( );
504:
505: while (!(Character.isWhitespace(next)))
506: {
507: result = result + next;
508: next = readChar( );
509: }
510:
511: if (next == '\r')
512: {
513: next = readChar( );
514: if (next != '\n')
515: {
516: System.out.println("Fatal error in method "
517: + "readWord of the class SavitchIn.");
518: System.exit(1);
519: }
520: }
521:
522: return result;
523: }
524:
525: /**
526: Precondition: The user has entered a number of type byte
527: on a line by itself, except that there may be whitespace
528: before and/or after the number.
529: Action: Reads and returns the number as a value of type
530: byte. The rest of the line is discarded. If the input is
531: not entered correctly, then in most cases, the user will
532: be asked to reenter the input. In particular, this applies
533: to incorrect number formats and blank lines.
534: */
535: public static byte readLineByte( )
536: {
537: String inputString = null;
538: byte number = -123;//To keep the compiler happy.
539: //Designed to look like a garbage value.
540: boolean done = false;
541:
542: while (! done)
543: {
544: try
545: {
546: inputString = readLine( );
547: inputString = inputString.trim( );
548: number = Byte.parseByte(inputString);
549: done = true;
550: }
551: catch (NumberFormatException e)
552: {
553: System.out.println(
554: "Your input number is not correct.");
555: System.out.println(
556: "Your input number must be a");
557: System.out.println(
558: "whole number in the range");
559: System.out.println("-128 to 127, written as");
560: System.out.println(
561: "an ordinary numeral, such as 42.");
562: System.out.println("Minus signs are OK,"
563: + "but do not use a plus sign.");
564: System.out.println("Please try again.");
565: System.out.println("Enter a whole number:");
566: }
567: }
568:
569: return number;
570: }
571:
572: /**
573: Precondition: The user has entered a number of type short
574: on a line by itself, except that there may be whitespace
575: before and/or after the number.
576: Action: Reads and returns the number as a value of type
577: short. The rest of the line is discarded. If the input is
578: not entered correctly, then in most cases, the user will
579: be asked to reenter the input. In particular, this applies
580: to incorrect number formats and blank lines.
581: */
582: public static short readLineShort( )
583: {
584: String inputString = null;
585: short number = -9999;//To keep the compiler happy.
586: //Designed to look like a garbage value.
587: boolean done = false;
588:
589: while (! done)
590: {
591: try
592: {
593: inputString = readLine( );
594: inputString = inputString.trim( );
595: number = Short.parseShort(inputString);
596: done = true;
597: }
598: catch (NumberFormatException e)
599: {
600: System.out.println(
601: "Your input number is not correct.");
602: System.out.println(
603: "Your input number must be a");
604: System.out.println(
605: "whole number in the range");
606: System.out.println(
607: "-32768 to 32767, written as");
608: System.out.println(
609: "an ordinary numeral, such as 42.");
610: System.out.println("Minus signs are OK,"
611: + "but do not use a plus sign.");
612: System.out.println("Please try again.");
613: System.out.println("Enter a whole number:");
614: }
615: }
616:
617: return number;
618: }
619:
620: public static byte readByte( ) throws NumberFormatException
621: {
622: String inputString = null;
623: inputString = readWord( );
624: return Byte.parseByte(inputString);
625: }
626:
627: public static short readShort( ) throws NumberFormatException
628: {
629: String inputString = null;
630: inputString = readWord( );
631: return Short.parseShort(inputString);
632: }
633:
634: //The following was intentionally not used in the code for
635: //other methods so that somebody reading the code could
636: //more quickly see what was being used.
637: /**
638: Reads the first byte in the input stream and returns that
639: byte as an int. The next read takes place where this one
640: left off. This read is the same as System.in.read( ),
641: except that it catches IOExceptions.
642: */
643: public static int read( )
644: {
645: int result = -1; //To keep the compiler happy
646: try
647: {
648: result = System.in.read( );
649: }
650: catch(IOException e)
651: {
652: System.out.println(e.getMessage( ));
653: System.out.println("Fatal error. Ending program.");
654: System.exit(0);
655: }
656: return result;
657: }
658: }