/*************************************************************************
* Compilation: javac StdIn.java
* Execution: java StdIn (interactive test of basic functionality)
*
* Reads in data of various types from standard input.
*
*************************************************************************/
importjava.util.ArrayList;importjava.util.InputMismatchException;importjava.util.Locale;importjava.util.Scanner;importjava.util.regex.Pattern;/*** The StdIn class provides static methods for reading strings
* and numbers from standard input. See
* Section 1.5 of
* Introduction to Programming in Java: An Interdisciplinary Approach
* by Robert Sedgewick and Kevin Wayne.
*
* For uniformity across platforms, this class uses Locale.US
* for the locale and "UTF-8" for the character-set encoding.
* The English language locale is consistent with the formatting conventions
* for Java floating-point literals, command-line arguments
* (via {@linkDouble#parseDouble(String)}) and standard output.
*
* Like {@linkScanner}, reading a token also consumes preceding Java
* whitespace; reading a line consumes the following end-of-line
* delimeter; reading a character consumes nothing extra.
*
* Whitespace is defined in {@linkCharacter#isWhitespace(char)}. Newlines
* consist of \n, \r, \r\n, and Unicode hex code points 0x2028, 0x2029, 0x0085;
* Scanner.java (NB: Java 6u23 and earlier uses only \r, \r, \r\n).
*
* See {@linkIn} for a version that handles input from files, URLs,
* and sockets.
*
* Note that Java's UTF-8 encoding does not recognize the optional byte-order
* mask. If the input begins with the optional byte-order mask, StdIn
* will have an extra character uFEFF at the beginning.
* For details, seehttp://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4508058.*
*@authorDavid Pritchard
*@authorRobert Sedgewick
*@authorKevin Wayne*/
public final classStdIn {//it doesn't make sense to instantiate this class
privateStdIn() { }private staticScanner scanner;/*** begin: section (1 of 2) of code duplicated from In to StdIn*/
//assume Unicode UTF-8 encoding
private static final String CHARSET_NAME = "UTF-8";//assume language = English, country = US for consistency with System.out.
private static final Locale LOCALE =Locale.US;//the default token separator; we maintain the invariant that this value//is held by the scanner's delimiter between calls
private static final Pattern WHITESPACE_PATTERN = Pattern.compile("\\p{javaWhitespace}+");//makes whitespace characters significant
private static final Pattern EMPTY_PATTERN = Pattern.compile("");//used to read the entire input
private static final Pattern EVERYTHING_PATTERN = Pattern.compile("\\A");/*** end: section (1 of 2) of code duplicated from In to StdIn*/
/*** begin: section (2 of 2) of code duplicated from In to StdIn,
* with all methods changed from "public" to "public static" ***/
/*** Is the input empty (except possibly for whitespace)? Use this
* to know whether the next call to {@link#readString()},
* {@link#readDouble()}, etc will succeed.
*@returntrue if standard input is empty (except possibly
* for whitespae), and false otherwise*/
public static booleanisEmpty() {return !scanner.hasNext();
}/*** Does the input have a next line? Use this to know whether the
* next call to {@link#readLine()} will succeed.
Functionally
* equivalent to {@link#hasNextChar()}.
*@returntrue if standard input is empty, and false otherwise*/
public static booleanhasNextLine() {returnscanner.hasNextLine();
}/*** Is the input empty (including whitespace)? Use this to know
* whether the next call to {@link#readChar()} will succeed.
*
Functionally equivalent to {@link#hasNextLine()}.
*@returntrue if standard input is empty, and false otherwise*/
public static booleanhasNextChar() {
scanner.useDelimiter(EMPTY_PATTERN);boolean result =scanner.hasNext();
scanner.useDelimiter(WHITESPACE_PATTERN);returnresult;
}/*** Reads and returns the next line, excluding the line separator if present.
*@returnthe next line, excluding the line separator if present*/
public staticString readLine() {
String line;try { line =scanner.nextLine(); }catch (Exception e) { line = null; }returnline;
}/*** Reads and returns the next character.
*@returnthe next character*/
public static charreadChar() {
scanner.useDelimiter(EMPTY_PATTERN);
String ch=scanner.next();assert (ch.length() == 1) : "Internal (Std)In.readChar() error!"
+ " Please contact the authors.";
scanner.useDelimiter(WHITESPACE_PATTERN);return ch.charAt(0);
}/*** Reads and returns the remainder of the input, as a string.
*@returnthe remainder of the input, as a string*/
public staticString readAll() {if (!scanner.hasNextLine())return "";
String result=scanner.useDelimiter(EVERYTHING_PATTERN).next();//not that important to reset delimeter, since now scanner is empty
scanner.useDelimiter(WHITESPACE_PATTERN); //but let's do it anyway
returnresult;
}/*** Reads the next token and returns the String.
*@returnthe next String*/
public staticString readString() {returnscanner.next();
}/*** Reads the next token from standard input, parses it as an integer, and returns the integer.
*@returnthe next integer on standard input
*@throwsInputMismatchException if the next token cannot be parsed as an int*/
public static intreadInt() {returnscanner.nextInt();
}/*** Reads the next token from standard input, parses it as a double, and returns the double.
*@returnthe next double on standard input
*@throwsInputMismatchException if the next token cannot be parsed as a double*/
public static doublereadDouble() {returnscanner.nextDouble();
}/*** Reads the next token from standard input, parses it as a float, and returns the float.
*@returnthe next float on standard input
*@throwsInputMismatchException if the next token cannot be parsed as a float*/
public static floatreadFloat() {returnscanner.nextFloat();
}/*** Reads the next token from standard input, parses it as a long integer, and returns the long integer.
*@returnthe next long integer on standard input
*@throwsInputMismatchException if the next token cannot be parsed as a long*/
public static longreadLong() {returnscanner.nextLong();
}/*** Reads the next token from standard input, parses it as a short integer, and returns the short integer.
*@returnthe next short integer on standard input
*@throwsInputMismatchException if the next token cannot be parsed as a short*/
public static shortreadShort() {returnscanner.nextShort();
}/*** Reads the next token from standard input, parses it as a byte, and returns the byte.
*@returnthe next byte on standard input
*@throwsInputMismatchException if the next token cannot be parsed as a byte*/
public static bytereadByte() {returnscanner.nextByte();
}/*** Reads the next token from standard input, parses it as a boolean,
* and returns the boolean.
*@returnthe next boolean on standard input
*@throwsInputMismatchException if the next token cannot be parsed as a boolean:
* true or 1 for true, and false or 0 for false,
* ignoring case*/
public static booleanreadBoolean() {
String s=readString();if (s.equalsIgnoreCase("true")) return true;if (s.equalsIgnoreCase("false")) return false;if (s.equals("1")) return true;if (s.equals("0")) return false;throw newInputMismatchException();
}/*** Reads all remaining tokens from standard input and returns them as an array of strings.
*@returnall remaining tokens on standard input, as an array of strings*/
public staticString[] readAllStrings() {//we could use readAll.trim().split(), but that's not consistent//because trim() uses characters 0x00..0x20 as whitespace
String[] tokens =WHITESPACE_PATTERN.split(readAll());if (tokens.length == 0 || tokens[0].length() > 0)returntokens;//don't include first token if it is leading whitespace
String[] decapitokens = new String[tokens.length-1];for (int i = 0; i < tokens.length - 1; i++)
decapitokens[i]= tokens[i+1];returndecapitokens;
}/*** Reads all remaining lines from standard input and returns them as an array of strings.
*@returnall remaining lines on standard input, as an array of strings*/
public staticString[] readAllLines() {
ArrayList lines = new ArrayList();while(hasNextLine()) {
lines.add(readLine());
}return lines.toArray(new String[0]);
}/*** Reads all remaining tokens from standard input, parses them as integers, and returns
* them as an array of integers.
*@returnall remaining integers on standard input, as an array
*@throwsInputMismatchException if any token cannot be parsed as an int*/
public static int[] readAllInts() {
String[] fields=readAllStrings();int[] vals = new int[fields.length];for (int i = 0; i < fields.length; i++)
vals[i]=Integer.parseInt(fields[i]);returnvals;
}/*** Reads all remaining tokens from standard input, parses them as doubles, and returns
* them as an array of doubles.
*@returnall remaining doubles on standard input, as an array
*@throwsInputMismatchException if any token cannot be parsed as a double*/
public static double[] readAllDoubles() {
String[] fields=readAllStrings();double[] vals = new double[fields.length];for (int i = 0; i < fields.length; i++)
vals[i]=Double.parseDouble(fields[i]);returnvals;
}/*** end: section (2 of 2) of code duplicated from In to StdIn*/
//do this once when StdIn is initialized
static{
resync();
}/*** If StdIn changes, use this to reinitialize the scanner.*/
private static voidresync() {
setScanner(new Scanner(newjava.io.BufferedInputStream(System.in), CHARSET_NAME));
}private static voidsetScanner(Scanner scanner) {
StdIn.scanner=scanner;
StdIn.scanner.useLocale(LOCALE);
}/*** Reads all remaining tokens, parses them as integers, and returns
* them as an array of integers.
*@returnall remaining integers, as an array
*@throwsInputMismatchException if any token cannot be parsed as an int
*@deprecatedFor more consistency, use {@link#readAllInts()}*/
public static int[] readInts() {returnreadAllInts();
}/*** Reads all remaining tokens, parses them as doubles, and returns
* them as an array of doubles.
*@returnall remaining doubles, as an array
*@throwsInputMismatchException if any token cannot be parsed as a double
*@deprecatedFor more consistency, use {@link#readAllDoubles()}*/
public static double[] readDoubles() {returnreadAllDoubles();
}/*** Reads all remaining tokens and returns them as an array of strings.
*@returnall remaining tokens, as an array of strings
*@deprecatedFor more consistency, use {@link#readAllStrings()}*/
public staticString[] readStrings() {returnreadAllStrings();
}/*** Interactive test of basic functionality.*/
public static voidmain(String[] args) {
System.out.println("Type a string: ");
String s=StdIn.readString();
System.out.println("Your string was: " +s);
System.out.println();
System.out.println("Type an int: ");int a =StdIn.readInt();
System.out.println("Your int was: " +a);
System.out.println();
System.out.println("Type a boolean: ");boolean b =StdIn.readBoolean();
System.out.println("Your boolean was: " +b);
System.out.println();
System.out.println("Type a double: ");double c =StdIn.readDouble();
System.out.println("Your double was: " +c);
System.out.println();
}
}