content: /*************************************************************************
   *  Compilation:  javac In.java
   *  Execution:    java In
   *
   *  Reads in data of various types from: stdin, file, URL.
   *
   *  % java In
   *
   *  Remarks
   *  -------
   *    - isEmpty() returns true if there is no more input or
   *      it is all whitespace. This might lead to surprising behavior
   *      when used with readChar()
   *
   *************************************************************************/
  
  
  import java.io.BufferedInputStream;
  import java.io.File;
  import java.io.IOException;
  import java.io.InputStream;
  import java.net.Socket;
  import java.net.URL;
  import java.net.URLConnection;
  import java.util.Locale;
  import java.util.Scanner;
  
  
  /**
   *  <i>Input</i>. This class provides methods for reading strings
   *  and numbers from standard input, file input, URL, and socket.
   *  <p>
   *  The Locale used is: language = English, country = US. This is consistent
   *  with the formatting conventions with Java floating-point literals,
   *  command-line arguments (via <tt>Double.parseDouble()</tt>)
   *  and standard output (via <tt>System.out.print()</tt>). It ensures that
   *  standard input works the number formatting used in the textbook.
   *  <p>
   *  For additional documentation, see <a href="http://introcs.cs.princeton.edu/31datatype">Section 3.1</a> of
   *  <i>Introduction to Programming in Java: An Interdisciplinary Approach</i> by Robert Sedgewick and Kevin Wayne.
   */
  public final class In {
      private Scanner scanner;
  
      // assume Unicode UTF-8 encoding
      //private String charsetName = "UTF-8";
  
      private String charsetName = "ISO-8859-1";
  
      // assume language = English, country = US for consistency with System.out.
      private Locale usLocale = new Locale("en", "US");
  
     /**
       * Create an input stream for standard input.
       */
      public In() {
          scanner = new Scanner(new BufferedInputStream(System.in), charsetName);
          scanner.useLocale(usLocale);
      }
  
     /**
       * Create an input stream from a socket.
       */
      public In(Socket socket) {
          try {
              InputStream is = socket.getInputStream();
              scanner = new Scanner(new BufferedInputStream(is), charsetName);
              scanner.useLocale(usLocale);
          }
          catch (IOException ioe) {
              System.err.println("Could not open " + socket);
          }
      }
  
     /**
       * Create an input stream from a URL.
       */
      public In(URL url) {
          try {
              URLConnection site = url.openConnection();
              InputStream is     = site.getInputStream();
              scanner            = new Scanner(new BufferedInputStream(is), charsetName);
              scanner.useLocale(usLocale);
          }
          catch (IOException ioe) {
              System.err.println("Could not open " + url);
          }
      }
  
     /**
       * Create an input stream from a file.
       */
      public In(File file) {
  
          try {
              scanner = new Scanner(file, charsetName);
              scanner.useLocale(usLocale);
          }
          catch (IOException ioe) {
              System.err.println("Could not open " + file);
          }
      }
  
  
     /**
       * Create an input stream from a filename or web page name.
       */
      public In(String s) {
  
          try {
              // first try to read file from local file system
              File file = new File(s);
              if (file.exists()) {
                  scanner = new Scanner(file, charsetName);
                  scanner.useLocale(usLocale);
                  return;
              }
  
              // next try for files included in jar
              URL url = getClass().getResource(s);
  
              // or URL from web
              if (url == null) { url = new URL(s); }
  
              URLConnection site = url.openConnection();
              InputStream is     = site.getInputStream();
              scanner            = new Scanner(new BufferedInputStream(is), charsetName);
              scanner.useLocale(usLocale);
          }
          catch (IOException ioe) {
              System.err.println("Could not open " + s);
          }
      }
  
     /**
       * Does the input stream exist?
       */
      public boolean exists()  {
          return scanner != null;
      }
  
     /**
       * Is the input stream empty?
       */
      public boolean isEmpty() {
          return !scanner.hasNext();
      }
  
     /**
       * Does the input stream have a next line?
       */
      public boolean hasNextLine() {
          return scanner.hasNextLine();
      }
  
     /**
       * Read and return the next line.
       */
      public String readLine() {
          String line;
          try                 { line = scanner.nextLine(); }
          catch (Exception e) { line = null;               }
          return line;
      }
  
     /**
       * Read and return the next character.
       */
      public char readChar() {
          // (?s) for DOTALL mode so . matches any character, including a line termination character
          // 1 says look only one character ahead
          // consider precompiling the pattern
          String s = scanner.findWithinHorizon("(?s).", 1);
          return s.charAt(0);
      }
  
  
  
      // return rest of input as string
     /**
       * Read and return the remainder of the input as a string.
       */
      public String readAll() {
          if (!scanner.hasNextLine()) { return null; }
  
          // reference: http://weblogs.java.net/blog/pat/archive/2004/10/stupid_scanner_1.html
          return scanner.useDelimiter("\\A").next();
      }
  
  
  
     /**
       * Return the next string from the input stream.
       */
      public String  readString() {
          return scanner.next();
      }
  
     /**
       * Return the next int from the input stream.
       */
      public int readInt() {
          return scanner.nextInt();
      }
  
     /**
       * Return the next double from the input stream.
       */
      public double readDouble() {
          return scanner.nextDouble();
      }
  
     /**
       * Return the next float from the input stream.
       */
      public double readFloat() {
          return scanner.nextFloat();
      }
  
     /**
       * Return the next long from the input stream.
       */
      public long readLong() {
          return scanner.nextLong();
      }
  
     /**
       * Return the next byte from the input stream.
       */
      public byte readByte() {
          return scanner.nextByte();
      }
  
  
     /**
       * Return the next boolean from the input stream, allowing "true" or "1"
       * for true and "false" or "0" for false.
       */
      public boolean readBoolean() {
          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 new java.util.InputMismatchException();
      }
  
     /**
       * Read ints from file
       */
      public static int[] readInts(String filename) {
          In in = new In(filename);
          String[] fields = in.readAll().trim().split("\\s+");
          int[] vals = new int[fields.length];
          for (int i = 0; i < fields.length; i++)
              vals[i] = Integer.parseInt(fields[i]);
          return vals;
      }
  
     /**
       * Read doubles from file
       */
      public static double[] readDoubles(String filename) {
          In in = new In(filename);
          String[] fields = in.readAll().trim().split("\\s+");
          double[] vals = new double[fields.length];
          for (int i = 0; i < fields.length; i++)
              vals[i] = Double.parseDouble(fields[i]);
          return vals;
      }
  
     /**
       * Read strings from a file
       */
      public static String[] readStrings(String filename) {
          In in = new In(filename);
          String[] fields = in.readAll().trim().split("\\s+");
          return fields;
      }
  
     /**
       * Read ints from standard input
       */
      public static int[] readInts() {
          In in = new In();
          String[] fields = in.readAll().trim().split("\\s+");
          int[] vals = new int[fields.length];
          for (int i = 0; i < fields.length; i++)
              vals[i] = Integer.parseInt(fields[i]);
          return vals;
      }
  
     /**
       * Read doubles from standard input
       */
      public static double[] readDoubles() {
          In in = new In();
          String[] fields = in.readAll().trim().split("\\s+");
          double[] vals = new double[fields.length];
          for (int i = 0; i < fields.length; i++)
              vals[i] = Double.parseDouble(fields[i]);
          return vals;
      }
  
     /**
       * Read strings from standard input
       */
      public static String[] readStrings() {
          In in = new In();
          String[] fields = in.readAll().trim().split("\\s+");
          return fields;
      }
  
     /**
       * Close the input stream.
       */
      public void close() { scanner.close();  }
  
  
  
     /**
       * Test client.
       */
      public static void main(String[] args) {
          In in;
          String urlName = "http://introcs.cs.princeton.edu/stdlib/InTest.txt";
  
          // read from a URL
          System.out.println("readAll() from URL " + urlName);
          System.out.println("---------------------------------------------------------------------------");
          try {
              in = new In(urlName);
              System.out.println(in.readAll());
          }
          catch (Exception e) { System.out.println(e); }
          System.out.println();
  
          // read one line at a time from URL
          System.out.println("readLine() from URL " + urlName);
          System.out.println("---------------------------------------------------------------------------");
          try {
              in = new In(urlName);
              while (!in.isEmpty()) {
                  String s = in.readLine();
                  System.out.println(s);
              }
          }
          catch (Exception e) { System.out.println(e); }
          System.out.println();
  
          // read one string at a time from URL
          System.out.println("readString() from URL " + urlName);
          System.out.println("---------------------------------------------------------------------------");
          try {
              in = new In(urlName);
              while (!in.isEmpty()) {
                  String s = in.readString();
                  System.out.println(s);
              }
          }
          catch (Exception e) { System.out.println(e); }
          System.out.println();
  
  
          // read one line at a time from file in current directory
          System.out.println("readLine() from current directory");
          System.out.println("---------------------------------------------------------------------------");
          try {
              in = new In("./InTest.txt");
              while (!in.isEmpty()) {
                  String s = in.readLine();
                  System.out.println(s);
              }
          }
          catch (Exception e) { System.out.println(e); }
          System.out.println();
  
  
          // read one line at a time from file using relative path
          System.out.println("readLine() from relative path");
          System.out.println("---------------------------------------------------------------------------");
          try {
              in = new In("../stdlib/InTest.txt");
              while (!in.isEmpty()) {
                  String s = in.readLine();
                  System.out.println(s);
              }
          }
          catch (Exception e) { System.out.println(e); }
          System.out.println();
  
          // read one char at a time
          System.out.println("readChar() from file");
          System.out.println("---------------------------------------------------------------------------");
          try {
              in = new In("InTest.txt");
              while (!in.isEmpty()) {
                  char c = in.readChar();
                  System.out.print(c);
              }
          }
          catch (Exception e) { System.out.println(e); }
          System.out.println();
          System.out.println();
  
          // read one line at a time from absolute OS X / Linux path
          System.out.println("readLine() from absolute OS X / Linux path");
          System.out.println("---------------------------------------------------------------------------");
          in = new In("/n/fs/csweb/introcs/stdlib/InTest.txt");
          try {
              while (!in.isEmpty()) {
                  String s = in.readLine();
                  System.out.println(s);
              }
          }
          catch (Exception e) { System.out.println(e); }
          System.out.println();
  
  
          // read one line at a time from absolute Windows path
          System.out.println("readLine() from absolute Windows path");
          System.out.println("---------------------------------------------------------------------------");
          try {
              in = new In("G:\\www\\introcs\\stdlib\\InTest.txt");
              while (!in.isEmpty()) {
                  String s = in.readLine();
                  System.out.println(s);
              }
              System.out.println();
          }
          catch (Exception e) { System.out.println(e); }
          System.out.println();
  
      }
  
  }
  