Source of SavitchIn.java


  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: }