/* The class EasyInput provides several static methods that make it easier to read from the standard input stream, System.in. The public methods defined in this class are: public static char getChar() -- Reads and returns the next character from System.in. If the next thing in system.in is an end-of-line, this returns '\n'. (Note that '\n' is always returned by this method to represent end-of-line -- even though some systems use '\r' or '\r' followed by '\n' to represent end-of-line internally.) public static int getInt() -- Reads and returns an integer from System.in. This method will skip white space (spaces, tabs, end-of-lines, etc.) before trying to read the integer. If it doesn't find a legal integer, it will print an error message on System.out and ask the user to try again. Note that when the method returns, you will always get a valid integer that was input by the user. public static double getDouble() -- Reads and returns a real number from System.in. This method will skip white space (spaces, tabs, end-of-lines) before trying to read the number. If it doesn't find a legal number, it will print an error message on System.out and ask the user to try again. Note that when the method returns, you will always get a valid integer that was input by the user. (Numbers of type double can include decimal points and exponents. For example: 3.14, 23e7, 123.45E-17) public static String getln() -- Reads characters up to and including the next end-of-line. Returns a string consisting of all the characters read, EXCLUDING the end-of-line. Note that the returned string can be empty, Often, you will call getln() without using the returned value; this is a simple way to discard the remainder of an input line after reading a character, integer, or double number. public static void skipWhiteSpace() -- Skips over any while space (tabs, spaces, end-of-line, etc.) in System.in. public static char lookChar() -- Lets you look ahead at the next character in the input, without removing it from the input stream. Like getChar(), this method returns '\n' to represent end-of-line. WARNING NOTE: When you use the input methods from class ConsoleInput, you should NOT read directly from System.in. (This class actually reads data from System.in in full-line chunks. There is no easy way to synchronize this with System.in.read() or other direct methods.) Also, you should not use this if System.in has been changed to be something other than the standard console input stream. */ import java.io.*; public class EasyInput { public static char lookChar() { if (pos > buf.length()) fillBuffer(); if (pos == buf.length()) return '\n'; else return buf.charAt(pos); } public static char getChar() { char ch = lookChar(); pos++; return ch; } public static void skipWhiteSpace() { while (Character.isSpace(lookChar())) getChar(); } public static String getln() { if (lookChar() == '\n') { pos = buf.length() + 1; return ""; } if (pos == 0) { pos = buf.length() + 1; return buf.toString(); } tempBuf.setLength(0); for ( ; pos < buf.length(); pos++) tempBuf.append(buf.charAt(pos)); pos = buf.length() + 1; return tempBuf.toString(); } public static int getInt() { long n = 0; while (true) { boolean neg; char ch = lookChar(); while (Character.isSpace(ch)) { if (ch == '\n') System.out.print("? "); getChar(); ch = lookChar(); } if (ch != '-' && ch != '+' && !Character.isDigit(ch)) { reportError("Found \"" + ch + "\" while looking for an integer.", "integer"); continue; } neg = (ch == '-'); if (ch == '+' || ch == '-') { getChar(); ch = lookChar(); if (!Character.isDigit(ch)) { reportError("Error while reading an integer; character following \"" + ch + "\" is not a digit.", "integer"); continue; } } n = 0; while (n <= Integer.MAX_VALUE && Character.isDigit(ch)) { n = 10*n + Character.digit(ch,10); getChar(); ch = lookChar(); } if (n > Integer.MAX_VALUE) { reportError("Integer value in input is too large; largest legal value is " + Integer.MAX_VALUE, "integer"); continue; } if (neg) n = -n; break; } return (int)n; } public static double getDouble() { double d = 0.0; while (true) { char ch = lookChar(); while (Character.isSpace(ch)) { if (ch == '\n') System.out.print("? "); getChar(); ch = lookChar(); } tempBuf.setLength(0); boolean neg = (ch == '-'); if (ch == '-' || ch == '+') { getChar(); ch = lookChar(); } if (ch != '.' && !Character.isDigit(ch)) { reportError("Found \"" + ch + "\" while looking for a real number.", "real number"); continue; } while (Character.isDigit(lookChar())) tempBuf.append(getChar()); if (lookChar() == '.') { tempBuf.append(getChar()); while (Character.isDigit(lookChar())) tempBuf.append(getChar()); } if (tempBuf.length() == 1 && tempBuf.charAt(0) == '.') { reportError("Found number with decimal point but no digits!", "real number"); continue; } ch = lookChar(); if (ch == 'e' || ch == 'E') { tempBuf.append(getChar()); ch = lookChar(); if (ch == '-' || ch == '+') { tempBuf.append(getChar()); ch = lookChar(); } if (!Character.isDigit(ch)) { reportError("No digits found in exponent part of number.", "real number"); continue; } while (Character.isDigit(lookChar())) tempBuf.append(getChar()); } Double D = null; try { D = new Double(tempBuf.toString()); } catch (NumberFormatException e) { D = null; } if (D == null) { reportError("Illegal number, \"" + tempBuf.toString() + "\", found in input.", "real number"); continue; } if (D.isInfinite()) { reportError("Input number, " + tempBuf.toString() + ", is outside of legal range for real numbers.", "real number"); continue; } d = D.doubleValue(); if (neg) d = -d; break; } return d; } // ------------------ PRIVATE VARIABLES AND METHODS -------------------- private static StringBuffer buf = new StringBuffer(); private static int pos = 1; private static boolean checkForLineFeed = false; private static StringBuffer tempBuf = new StringBuffer(); private static void fillBuffer() { buf.setLength(0); pos = 0; try { int ch; ch = System.in.read(); if (checkForLineFeed && ch == '\n') ch = System.in.read(); if (ch == -1) return; while (ch != -1 && ch != '\r' && ch != '\n') { buf.append((char)ch); ch = System.in.read(); } checkForLineFeed = (ch == '\r'); } catch (IOException e) { throw new RuntimeException("Unexpected IO error while reading from System.in in class ConsoleInput."); } } private static void reportError(String message, String type) { System.out.println(); System.out.println("*** " + message); if (pos >= buf.length()) { System.out.println("*** Discarding input: (end of line)"); getln(); } else System.out.println("*** Discarding input: " + getln()); System.out.println("*** Please try again with a legal " + type + '.'); System.out.println(); System.out.print("? "); } }