// © Copyright 1997, Joseph Bergin. All rights reserved. package cs1; import java.io.InputStream; import java.io.Reader; import java.io.InputStreamReader; import java.io.BufferedReader; import java.util.StringTokenizer; import java.io.IOException; import java.io.PrintStream; import java.io.PrintWriter; import java.util.NoSuchElementException; /** Provides line buffered input that can be used either interactively * or from a file. In interactive mode (using a non-null prompt file), * one item is read per line. In "batch" mode (prompt = null), lines * may contain several elements. Note that getLine * retrieves the rest of the current line. In non-interactive mode, * tokens will be skipped to try to find one of the desired kind. For * example if you getInt() when the next input token is not a legal int, * tokens will be skipped looking for an int. Failure will come at the * end of the file, of course.

* Sources: SafeInput.java */ public class SafeInput { /** Create a new inputter. The PrintStream is used to prompt the user. Data is read * from the InputFlie. If the input stream is a file, then the print stream * used for prompting should be null. * @param prompt A print stream used for prompting interactively. If null, no * prompting will be done. * @param in The input stream to be read. */ public SafeInput(PrintStream prompt, InputStream in) // if prompt is null, no prompting will be done. { input = new BufferedReader(new InputStreamReader(in)); output = new PrintWriter(prompt); } /** Create a new inputter. The PrintWriter is used to prompt the user. Data is read * from the Reader. If the input stream is a file, then the print stream * used for prompting should be null. * @param prompt A PrintWriter used for prompting interactively. If null, no * prompting will be done. * @param in The input stream to be read. */ public SafeInput(PrintWriter prompt, Reader in) // if prompt is null, no prompting will be done. { input = new BufferedReader(in); output = prompt; } /** Guarantees that we have a non-empty line buffer. */ private void guaranteeBuffer() { try { if( inBuffer == null || ! fetcher.hasMoreElements() ) { while(fetcher == null || ! fetcher.hasMoreElements()) { inBuffer = input.readLine(); fetcher = new StringTokenizer(inBuffer, delimiters); } } } catch(NoSuchElementException e) { System.err.println(e); } catch(IOException e) { System.err.println(e); } } /** Get an int from the next location in the input. When used interactively * the user will be continuously prompted until a valid int is entered. */ public int getInt() { int result = 0; boolean inputOk = false; while(!inputOk) { if(output != null){inBuffer = null; fetcher = null; output.print("Enter an integer: "); output.flush();} guaranteeBuffer(); inputOk = true; try { result = Integer.parseInt(fetcher.nextToken(delimiters)); } catch(NumberFormatException e) { inputOk = false; if(output != null){output.println("Not an integer.");} } } return result; } /** Get a float from the next location in the input. When used interactively * the user will be continuously prompted until a valid float is entered. */ public float getFloat() { float result = 0; boolean inputOk = false; while(!inputOk) { if(output != null){inBuffer = null; fetcher = null; output.print("Enter a float: "); output.flush();} guaranteeBuffer(); inputOk = true; try { result = Float.valueOf(fetcher.nextToken(delimiters)).floatValue(); } catch(NumberFormatException e) { inputOk = false; if(output != null){output.println("Not a float.");} } } return result; } /** Get a double from the next location in the input. When used interactively * the user will be continuously prompted until a valid double is entered. */ public double getDouble() { double result = 0; boolean inputOk = false; while(!inputOk) { if(output != null){inBuffer = null; fetcher = null; output.print("Enter a double: "); output.flush();} guaranteeBuffer(); inputOk = true; try { result = Double.valueOf(fetcher.nextToken(delimiters)).doubleValue(); } catch(NumberFormatException e) { inputOk = false; if(output != null){output.println("Not a double.");} } } return result; } /** Get a long from the next location in the input. When used interactively * the user will be continuously prompted until a valid long is entered. */ public long getLong() { long result = 0; boolean inputOk = false; while(!inputOk) { if(output != null){inBuffer = null; fetcher = null; output.print("Enter a long: "); output.flush();} guaranteeBuffer(); inputOk = true; try { result = Long.parseLong(fetcher.nextToken(delimiters)); } catch(NumberFormatException e) { inputOk = false; if(output != null){output.println("Not a long.");} } } return result; } /** Get a word from the next location in the input. In interactive mode, * a new line will be read first. */ public String getWord() { if(output != null){inBuffer = null; fetcher = null; output.print("Enter a word: "); output.flush();} guaranteeBuffer(); return fetcher.nextToken(delimiters); } /** Get the remainder of the current line buffer as input. In interactive * mode, a fresh line will be read entirely. */ public String getLine() { if(output != null){inBuffer = null; fetcher = null; output.print("Enter a line of text: "); output.flush();} guaranteeBuffer(); String result = fetcher.nextToken(""); return result; } /** Set the delimiters that are used to separate tokens. The default set * is space and tab only. * @param newDelimiters the new set of delimiting chars in a String. * @return the original set of delimiters. */ public String setDelimiters(String newDelimiters) // returns old delimiters // The default delimiters are just spacs and tab. { String result = delimiters; delimiters = newDelimiters; return result; } private String inBuffer = null; private PrintWriter output; private StringTokenizer fetcher = null; private BufferedReader input; private String delimiters = " \t"; }