001: import java.io.*;
002: import java.util.*;
003: 
004: 
005: /****************************************************************
006:  *Class for simple console input.
007:  *A class designed primarily for simple keyboard input of the form
008:  *one input value per line. If the user enters an improper input,
009:  *i.e., an input of the wrong type or a blank line, then the user
010:  *is prompted to reenter the input and given a brief explanation
011:  *of what is required. Also includes some additional methods to
012:  *input single numbers, words, and characters, without going to
013:  *the next line.
014:  ***************************************************************/
015: public class SavitchIn
016: {
017: 
018:     /***********************************************************
019:      *Reads a line of text and returns that line as a String value.
020:      *The end of a line must be indicated either by a new line
021:      *character '\n' or by a carriage return '\r' followed by a
022:      *new line character '\n'. (Almost all systems do this
023:      *automatically. So, you need not worry about this detail.)
024:      *Neither the '\n', nor the '\r' if present, are part of the
025:      *string returned. This will read the rest of a line if the 
026:      *line is already partially read.
027:      **********************************************************/
028:     public static String readLine()
029:     { 
030:         char nextChar;
031:         String result = "";
032:         boolean done = false;
033:        
034:         while (!done)
035:         {
036:             nextChar = readChar();
037:             if (nextChar == '\n')
038:                done = true;
039:             else if (nextChar == '\r')
040:             {
041:                 //Do nothing.
042:                 //Next loop iteration will detect '\n'
043:             }
044:             else 
045:                result = result + nextChar;
046:         }
047:         
048:         return result;
049:     }
050: 
051: 
052:     /************************************************************
053:      *Reads the first string of nonwhite characters on a line and
054:      *returns that string. The rest of the line is discarded. If
055:      *the line contains only white space, then the user is asked
056:      *to reenter the line.
057:      ************************************************************/
058:     public static String readLineWord() 
059:     {
060:         String inputString = null,
061:                result = null;
062:         boolean done = false;
063:         
064:         while(!done)
065:         {
066:             inputString = readLine();
067:             StringTokenizer wordSource = 
068:                                 new StringTokenizer(inputString);
069:             if (wordSource.hasMoreTokens())
070:             {
071:                 result = wordSource.nextToken();
072:                 done = true;
073:             }
074:             else
075:             {
076:                 System.out.println(
077:                        "Your input is not correct. Your input must");
078:                 System.out.println(
079:                     "contain at least one nonwhitespace character.");
080:                 System.out.println(
081:                                  "Please, try again. Enter input:");
082:            }
083:        }
084:        
085:        return result;
086:    }
087:     
088: 
089:     /************************************************************
090:      *Precondition: The user has entered a number of type int on
091:      *a line by itself, except that there may be white space before
092:      *and/or after the number.
093:      *Action: Reads and returns the number as a value of type int.
094:      *The rest of the line is discarded. If the input is not 
095:      *entered correctly, then in most cases, the user will be
096:      *asked to reenter the input. In particular, this applies to
097:      *incorrect number formats and blank lines. 
098:      ************************************************************/
099:     public static int readLineInt()  
100:     {
101:         String inputString = null;
102:         int number = -9999;//To keep the compiler happy. 
103:                               //Designed to look like a garbage value.
104:         boolean done = false;
105:         
106:         while (! done)
107:         {
108:             try
109:             { 
110:                 inputString = readLine();
111:                 inputString = inputString.trim();
112:                 number = (Integer.valueOf(inputString).intValue());
113:                 done = true; 
114:             }
115:             catch (NumberFormatException e)
116:             {
117:                 System.out.println(
118:                                 "Your input number is not correct.");
119:                 System.out.println("Your input number must be");
120:                 System.out.println("a whole number written as an");
121:                 System.out.println("ordinary numeral, such as 42");
122:                 System.out.println("Please, try again.");
123:                 System.out.println("Enter a whole number:");
124:             }
125:         }
126:        
127:         return number; 
128:     }
129:   
130:  
131:     /************************************************************
132:      *Precondition: The user has entered a number of type long on
133:      *a line by itself, except that there may be white space 
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 not
137:      *entered correctly, then in most cases, the user will be asked
138:      *to reenter the input. In particular, this applies to 
139:      *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.valueOf(inputString).longValue()); 
155:                 done = true; 
156:             }
157:             catch (NumberFormatException e)
158:             {
159:                 System.out.println(
160:                                 "Your input number is not correct.");
161:                 System.out.println("Your input number must be");
162:                 System.out.println("a whole number written as an");
163:                 System.out.println("ordinary numeral, such as 42");
164:                 System.out.println("Please, try again.");
165:                 System.out.println("Enter a whole number:");
166:             }
167:        }
168:        
169:         return number;       
170:     }
171:   
172:   
173:      /**********************************************************
174:      *Precondition: The user has entered a number of type double
175:      *on a line by itself, except that there may be white space
176:      *before and/or after the number.
177:      *Action: Reads and returns the number as a value of type
178:      *double. The rest of the line is discarded. If the input is
179:      *not entered correctly, then in most cases, the user will be
180:      *asked to reenter the input. In particular, this applies to
181:      *incorrect number formats and blank lines. 
182:      ***********************************************************/
183:     public static double readLineDouble() 
184:     {
185:         String inputString = null;
186:         double number = -9999;//To keep the compiler happy.
187:                               //Designed to look like a garbage value.
188:         boolean done = false;
189:         
190:         while (! done)
191:         {
192:             try
193:             { 
194:                 inputString = readLine();
195:                 inputString = inputString.trim();
196:                 number = (Double.valueOf(inputString).doubleValue()); 
197:                 done = true; 
198:             }
199:             catch (NumberFormatException e)
200:             {
201:                 System.out.println(
202:                                 "Your input number is not correct.");
203:                 System.out.println("Your input number must be");
204:                 System.out.println("an ordinary number either with");
205:                 System.out.println("or without a decimal point,");
206:                 System.out.println("such as 42 or 9.99"); 
207:                 System.out.println("Please, try again.");
208:                 System.out.println("Enter a whole number:");
209:             }
210:         }
211:        
212:         return number;
213:     }
214:  
215:   
216:     /************************************************************
217:      *Precondition: The user has entered a number of type float
218:      *on a line by itself, except that there may be white space
219:      *before and/or after the number.
220:      *Action: Reads and returns the number as a value of type
221:      *float. The rest of the line is discarded. If the input is
222:      *not entered correctly, then in most cases, the user will 
223:      *be asked to reenter the input. In particular, 
224:      *this applies to incorrect number formats and blank lines.
225:      ************************************************************/
226:     public static float readLineFloat() 
227:     {
228:         String inputString = null;
229:         float number = -9999;//To keep the compiler happy.
230:                               //Designed to look like a garbage value.
231:         boolean done = false;
232:         
233:         while (! done)
234:         {
235:             try
236:             { 
237:                 inputString = readLine();
238:                 inputString = inputString.trim();
239:                 number = (Float.valueOf(inputString).floatValue());
240:                 done = true; 
241:             }
242:             catch (NumberFormatException e)
243:             {
244:                 System.out.println(
245:                                 "Your input number is not correct.");
246:                 System.out.println("Your input number must be");
247:                 System.out.println("an ordinary number either with");
248:                 System.out.println("or without a decimal point,");
249:                 System.out.println("such as 42 or 9.99"); 
250:                 System.out.println("Please, try again.");
251:                 System.out.println("Enter a whole number:");
252:             }
253:         }
254:        
255:         return number;
256:     }
257:   
258: 
259:     /************************************************************
260:      *Reads the first Nonwhite character on a line and returns
261:      *that character. The rest of the line is discarded. If the
262:      *line contains only white space, then the user is asked to
263:      *reenter the line.
264:      ************************************************************/
265:     public static char readLineNonwhiteChar() 
266:     {
267:         boolean done = false;
268:         String inputString = null;
269:         char nonWhite = ' ';//To keep the compiler happy. 
270:         
271:         while (! done)
272:         {
273:             inputString = readLine();
274:             inputString = inputString.trim(); 
275:             if (inputString.length() == 0)   
276:             {
277:                 System.out.println(
278:                                 "Your input is not correct.");
279:                 System.out.println("Your input must contain at");
280:                 System.out.println(
281:                               "least one nonwhitespace character.");
282:                 System.out.println("Please, try again.");
283:                 System.out.println("Enter input:");
284:             }
285:             else
286:             {                                    
287:                 nonWhite = (inputString.charAt(0)); 
288:                 done = true;
289:             }
290:         }
291:         
292:         return nonWhite;
293:     }
294: 
295: 
296:     /***********************************************************
297:      *Input should consists of a single word on a line, possibly
298:      *surrounded by white space.  The line is read and discarded.
299:      *If the input word is "true" or "t", then true is returned.
300:      *If the input word is "false" or "f", then false is returned.
301:      *Uppercase and lowercase letters are considered equal. If the
302:      *user enters anything else (e.g. multiple words or different
303:      *words), then, the user is asked to reenter the input.
304:      ***********************************************************/ 
305:     public static boolean readLineBoolean() 
306:     {
307:         boolean done = false;
308:         String inputString = null;
309:         boolean result = false;//To keep the compiler happy.
310:         
311:         while (! done)
312:         {
313:             inputString = readLine();
314:             inputString = inputString.trim(); 
315:             if (inputString.equalsIgnoreCase("true")
316:                    || inputString.equalsIgnoreCase("t"))
317:             {
318:                 result = true;
319:                 done = true;
320:             }
321:             else if (inputString.equalsIgnoreCase("false")
322:                         || inputString.equalsIgnoreCase("f"))
323:             {
324:                 result = false;
325:                 done = true;
326:             }
327:             else 
328:             {
329:                 System.out.println(
330:                                 "Your input number is not correct.");
331:                 System.out.println("Your input number must be");
332:                 System.out.println("one of the following:");
333:                 System.out.println("the word true,");
334:                 System.out.println("the word false,");
335:                 System.out.println("the letter T,");
336:                 System.out.println("or the letter F.");
337:                 System.out.println("You may use either uppercase");
338:                 System.out.println("or lowercase letters.");
339:                 System.out.println("Please, try again.");
340:                 System.out.println("Enter input:");
341:             }
342:          }
343:         
344:         return result;
345:     }
346:  
347: 
348:     /************************************************************
349:      *Reads the next input character and returns that character. The
350:      *next read takes place on the same line where this one left off.
351:      ***********************************************************/
352:     public static char readChar()
353:     {
354:         int charAsInt = -1; //To keep the compiler happy
355:         try
356:         {
357:             charAsInt = System.in.read(); 
358:         }
359:         catch(IOException e)
360:         {
361:             System.out.println(e.getMessage());
362:             System.out.println("Fatal error. Ending Program.");
363:             System.exit(0);          
364:         } 
365:         
366:         return (char)charAsInt;         
367:     }
368:  
369: 
370:     /***********************************************************
371:      *Reads the next nonwhite input character and returns that
372:      *character. The next read takes place immediately after
373:      *the character read. 
374:      **********************************************************/
375:     public static char readNonwhiteChar()  
376:     { 
377:       char next;
378:  
379:       next =  readChar();
380:       while (Character.isWhitespace(next))
381:           next =  readChar();
382:       
383:       return next;
384:     }
385: 
386: 
387:     /***********************************************************
388:      *The following methods are not used in the text, except for
389:      *a brief reference in Chapter 2. No program code uses them.
390:      *However, some programmers may want to use them.
391:      **********************************************************/
392: 
393:     /************************************************************
394:      *Precondition: The next input in the stream consists of an
395:      *int value, possibly preceded by white space, but definitely
396:      *followed by white space.
397:      *Action: Reads the first string of nonwhite characters
398:      *and returns the int value it represents. Discards the first
399:      *whitespace character after the word. The next read takes
400:      *place immediately after the discarded whitespace. 
401:      *In particular, if the word is at the end of a line, the
402:      *next reading will take place starting on the next line. 
403:      *If the next word does not represent an int value,
404:      *a NumberFormatException is thrown.
405:      ***********************************************************/
406:     public static int readInt() throws NumberFormatException 
407:     { 
408:         String inputString = null;
409:         inputString = readWord(); 
410:         return (Integer.valueOf(inputString).intValue()); 
411:     }
412:    
413:  
414:     /************************************************************
415:      *Precondition: The next input consists of a long value,
416:      *possibly preceded by white space, but definitely
417:      *followed by white space.
418:      *Action: Reads the first string of nonwhite characters and
419:      *returns the long value it represents. Discards the first
420:      *whitespace character after the string read. The next read
421:      *takes place immediately after the discarded whitespace.
422:      *In particular, if the string read is at the end of a line,
423:      *the next reading will take place starting on the next line.
424:      *If the next word does not represent a long value,
425:      *a NumberFormatException is thrown.
426:      ************************************************************/
427:     public static long readLong() 
428:                       throws NumberFormatException
429:     { 
430:         String inputString = null;
431:         inputString = readWord(); 
432:         return (Long.valueOf(inputString).longValue()); 
433:     }
434:   
435:  
436:     /***********************************************************
437:      *Precondition: The next input consists of a double value,
438:      *possibly preceded by white space, but definitely
439:      *followed by white space.
440:      *Action: Reads the first string of nonwhitespace characters
441:      *and returns the double value it represents. Discards the
442:      *first whitespace character after the string read. The next
443:      *read takes place immediately after the discarded whitespace.
444:      *In particular, if the string read is at the end of a line,
445:      *the next reading will take place starting on the next line.
446:      *If the next word does not represent a double value,
447:      *a NumberFormatException is thrown.
448:      ************************************************************/
449:     public static double readDouble() 
450:                        throws NumberFormatException
451:     { 
452:         String inputString = null;
453:         inputString = readWord(); 
454:         return (Double.valueOf(inputString).doubleValue()); 
455:     }
456:    
457: 
458:     /***********************************************************
459:      *Precondition: The next input consists of a float value,
460:      *possibly preceded by white space, but definitely
461:      *followed by white space.
462:      *Action: Reads the first string of nonwhite characters and
463:      *returns the float value it represents. Discards the first
464:      *whitespace character after the string read. The next read
465:      *takes place immediately after the discarded whitespace.
466:      *In particular, if the string read is at the end of a line,
467:      *the next reading will take place starting on the next line.
468:      *If the next word does not represent a float value,
469:      *a NumberFormatException is thrown.
470:      ************************************************************/
471:     public static float readFloat() 
472:                          throws NumberFormatException
473:     { 
474:         String inputString = null;
475:         inputString = readWord(); 
476:         return (Float.valueOf(inputString).floatValue()); 
477:     }
478:   
479: 
480:     /***********************************************************
481:      *Reads the first string of nonwhite characters and returns
482:      *that string. Discards the first whitespace character after
483:      *the string read. The next read takes place immediately after
484:      *the  discarded whitespace. In particular, if the string
485:      *read is at the end of a line, the next reading will take 
486:      *place starting on the next line. Note, that if it receives
487:      *blank lines, it will wait until it gets a nonwhitespace
488:      *character.
489:      ************************************************************/
490:     public static String readWord()  
491:     { 
492:         String result = "";
493:         char next; 
494:         
495:         next =  readChar();
496:         while (Character.isWhitespace(next))
497:              next =  readChar(); 
498:            
499:         while (!(Character.isWhitespace(next)))
500:         { 
501:             result = result + next; 
502:             next =  readChar();
503:         }
504:         
505:         if (next == '\r')
506:         {
507:             next = readChar();
508:             if (next != '\n')
509:             {
510:                 System.out.println("Fatal Error in method readWord of class SavitchIn.");
511:                 System.exit(1);
512:             }
513:         }
514: 
515:         return result;
516:     }
517: 
518: 
519:     //The following was intentionally not used in the code for
520:     //other methods so that somebody reading the code could more
521:     //quickly see what was being used.
522:     /************************************************************
523:      *Reads the first byte in the input stream and returns that
524:      * byte as an int. The next read takes place where this one 
525:      *left off. This read is the same as System.in.read(),
526:      *except that it catches IOExceptions.
527:      ************************************************************/
528:     public static int read()   
529:     {
530:         int result = -1; //To keep the compiler happy
531:         try
532:         {
533:             result = System.in.read();
534:         }
535:         catch(IOException e)
536:         {
537:             System.out.println(e.getMessage());
538:             System.out.println("Fatal error. Ending Program.");
539:             System.exit(0);          
540:         }         
541:         return result;
542:     }
543: }