< prev index next >

src/java.base/share/classes/java/util/Scanner.java

Print this page




  25 
  26 package java.util;
  27 
  28 import java.nio.file.Path;
  29 import java.nio.file.Files;
  30 import java.util.regex.*;
  31 import java.io.*;
  32 import java.math.*;
  33 import java.nio.*;
  34 import java.nio.channels.*;
  35 import java.nio.charset.*;
  36 import java.text.*;
  37 import java.util.Locale;
  38 
  39 import sun.misc.LRUCache;
  40 
  41 /**
  42  * A simple text scanner which can parse primitive types and strings using
  43  * regular expressions.
  44  *
  45  * <p>A <code>Scanner</code> breaks its input into tokens using a
  46  * delimiter pattern, which by default matches whitespace. The resulting
  47  * tokens may then be converted into values of different types using the
  48  * various <tt>next</tt> methods.
  49  *
  50  * <p>For example, this code allows a user to read a number from
  51  * <tt>System.in</tt>:
  52  * <blockquote><pre>{@code
  53  *     Scanner sc = new Scanner(System.in);
  54  *     int i = sc.nextInt();
  55  * }</pre></blockquote>
  56  *
  57  * <p>As another example, this code allows <code>long</code> types to be
  58  * assigned from entries in a file <code>myNumbers</code>:
  59  * <blockquote><pre>{@code
  60  *      Scanner sc = new Scanner(new File("myNumbers"));
  61  *      while (sc.hasNextLong()) {
  62  *          long aLong = sc.nextLong();
  63  *      }
  64  * }</pre></blockquote>
  65  *
  66  * <p>The scanner can also use delimiters other than whitespace. This
  67  * example reads several items in from a string:
  68  * <blockquote><pre>{@code
  69  *     String input = "1 fish 2 fish red fish blue fish";
  70  *     Scanner s = new Scanner(input).useDelimiter("\\s*fish\\s*");
  71  *     System.out.println(s.nextInt());
  72  *     System.out.println(s.nextInt());
  73  *     System.out.println(s.next());
  74  *     System.out.println(s.next());
  75  *     s.close();
  76  * }</pre></blockquote>
  77  * <p>
  78  * prints the following output:


  89  *     String input = "1 fish 2 fish red fish blue fish";
  90  *     Scanner s = new Scanner(input);
  91  *     s.findInLine("(\\d+) fish (\\d+) fish (\\w+) fish (\\w+)");
  92  *     MatchResult result = s.match();
  93  *     for (int i=1; i<=result.groupCount(); i++)
  94  *         System.out.println(result.group(i));
  95  *     s.close();
  96  * }</pre></blockquote>
  97  *
  98  * <p>The <a name="default-delimiter">default whitespace delimiter</a> used
  99  * by a scanner is as recognized by {@link java.lang.Character}.{@link
 100  * java.lang.Character#isWhitespace(char) isWhitespace}. The {@link #reset}
 101  * method will reset the value of the scanner's delimiter to the default
 102  * whitespace delimiter regardless of whether it was previously changed.
 103  *
 104  * <p>A scanning operation may block waiting for input.
 105  *
 106  * <p>The {@link #next} and {@link #hasNext} methods and their
 107  * primitive-type companion methods (such as {@link #nextInt} and
 108  * {@link #hasNextInt}) first skip any input that matches the delimiter
 109  * pattern, and then attempt to return the next token. Both <tt>hasNext</tt>
 110  * and <tt>next</tt> methods may block waiting for further input.  Whether a
 111  * <tt>hasNext</tt> method blocks has no connection to whether or not its
 112  * associated <tt>next</tt> method will block.
 113  *
 114  * <p> The {@link #findInLine}, {@link #findWithinHorizon}, and {@link #skip}
 115  * methods operate independently of the delimiter pattern. These methods will
 116  * attempt to match the specified pattern with no regard to delimiters in the
 117  * input and thus can be used in special circumstances where delimiters are
 118  * not relevant. These methods may block waiting for more input.
 119  *
 120  * <p>When a scanner throws an {@link InputMismatchException}, the scanner
 121  * will not pass the token that caused the exception, so that it may be
 122  * retrieved or skipped via some other method.
 123  *
 124  * <p>Depending upon the type of delimiting pattern, empty tokens may be
 125  * returned. For example, the pattern <tt>"\\s+"</tt> will return no empty
 126  * tokens since it matches multiple instances of the delimiter. The delimiting
 127  * pattern <tt>"\\s"</tt> could return empty tokens since it only passes one
 128  * space at a time.
 129  *
 130  * <p> A scanner can read text from any object which implements the {@link
 131  * java.lang.Readable} interface.  If an invocation of the underlying
 132  * readable's {@link java.lang.Readable#read} method throws an {@link
 133  * java.io.IOException} then the scanner assumes that the end of the input
 134  * has been reached.  The most recent <tt>IOException</tt> thrown by the
 135  * underlying readable can be retrieved via the {@link #ioException} method.
 136  *
 137  * <p>When a <code>Scanner</code> is closed, it will close its input source
 138  * if the source implements the {@link java.io.Closeable} interface.
 139  *
 140  * <p>A <code>Scanner</code> is not safe for multithreaded use without
 141  * external synchronization.
 142  *
 143  * <p>Unless otherwise mentioned, passing a <code>null</code> parameter into
 144  * any method of a <code>Scanner</code> will cause a
 145  * <code>NullPointerException</code> to be thrown.
 146  *
 147  * <p>A scanner will default to interpreting numbers as decimal unless a
 148  * different radix has been set by using the {@link #useRadix} method. The
 149  * {@link #reset} method will reset the value of the scanner's radix to
 150  * <code>10</code> regardless of whether it was previously changed.
 151  *
 152  * <h3> <a name="localized-numbers">Localized numbers</a> </h3>
 153  *
 154  * <p> An instance of this class is capable of scanning numbers in the standard
 155  * formats as well as in the formats of the scanner's locale. A scanner's
 156  * <a name="initial-locale">initial locale </a>is the value returned by the {@link
 157  * java.util.Locale#getDefault(Locale.Category)
 158  * Locale.getDefault(Locale.Category.FORMAT)} method; it may be changed via the {@link
 159  * #useLocale} method. The {@link #reset} method will reset the value of the
 160  * scanner's locale to the initial locale regardless of whether it was
 161  * previously changed.
 162  *
 163  * <p>The localized formats are defined in terms of the following parameters,
 164  * which for a particular locale are taken from that locale's {@link
 165  * java.text.DecimalFormat DecimalFormat} object, <tt>df</tt>, and its and
 166  * {@link java.text.DecimalFormatSymbols DecimalFormatSymbols} object,
 167  * <tt>dfs</tt>.
 168  *
 169  * <blockquote><dl>
 170  *     <dt><i>LocalGroupSeparator&nbsp;&nbsp;</i>
 171  *         <dd>The character used to separate thousands groups,
 172  *         <i>i.e.,</i>&nbsp;<tt>dfs.</tt>{@link
 173  *         java.text.DecimalFormatSymbols#getGroupingSeparator
 174  *         getGroupingSeparator()}
 175  *     <dt><i>LocalDecimalSeparator&nbsp;&nbsp;</i>
 176  *         <dd>The character used for the decimal point,
 177  *     <i>i.e.,</i>&nbsp;<tt>dfs.</tt>{@link
 178  *     java.text.DecimalFormatSymbols#getDecimalSeparator
 179  *     getDecimalSeparator()}
 180  *     <dt><i>LocalPositivePrefix&nbsp;&nbsp;</i>
 181  *         <dd>The string that appears before a positive number (may
 182  *         be empty), <i>i.e.,</i>&nbsp;<tt>df.</tt>{@link
 183  *         java.text.DecimalFormat#getPositivePrefix
 184  *         getPositivePrefix()}
 185  *     <dt><i>LocalPositiveSuffix&nbsp;&nbsp;</i>
 186  *         <dd>The string that appears after a positive number (may be
 187  *         empty), <i>i.e.,</i>&nbsp;<tt>df.</tt>{@link
 188  *         java.text.DecimalFormat#getPositiveSuffix
 189  *         getPositiveSuffix()}
 190  *     <dt><i>LocalNegativePrefix&nbsp;&nbsp;</i>
 191  *         <dd>The string that appears before a negative number (may
 192  *         be empty), <i>i.e.,</i>&nbsp;<tt>df.</tt>{@link
 193  *         java.text.DecimalFormat#getNegativePrefix
 194  *         getNegativePrefix()}
 195  *     <dt><i>LocalNegativeSuffix&nbsp;&nbsp;</i>
 196  *         <dd>The string that appears after a negative number (may be
 197  *         empty), <i>i.e.,</i>&nbsp;<tt>df.</tt>{@link
 198  *     java.text.DecimalFormat#getNegativeSuffix
 199  *     getNegativeSuffix()}
 200  *     <dt><i>LocalNaN&nbsp;&nbsp;</i>
 201  *         <dd>The string that represents not-a-number for
 202  *         floating-point values,
 203  *         <i>i.e.,</i>&nbsp;<tt>dfs.</tt>{@link
 204  *         java.text.DecimalFormatSymbols#getNaN
 205  *         getNaN()}
 206  *     <dt><i>LocalInfinity&nbsp;&nbsp;</i>
 207  *         <dd>The string that represents infinity for floating-point
 208  *         values, <i>i.e.,</i>&nbsp;<tt>dfs.</tt>{@link
 209  *         java.text.DecimalFormatSymbols#getInfinity
 210  *         getInfinity()}
 211  * </dl></blockquote>
 212  *
 213  * <h4> <a name="number-syntax">Number syntax</a> </h4>
 214  *
 215  * <p> The strings that can be parsed as numbers by an instance of this class
 216  * are specified in terms of the following regular-expression grammar, where
 217  * Rmax is the highest digit in the radix being used (for example, Rmax is 9 in base 10).
 218  *
 219  * <dl>
 220  *   <dt><i>NonAsciiDigit</i>:
 221  *       <dd>A non-ASCII character c for which
 222  *            {@link java.lang.Character#isDigit Character.isDigit}<tt>(c)</tt>
 223  *                        returns&nbsp;true
 224  *
 225  *   <dt><i>Non0Digit</i>:
 226  *       <dd><tt>[1-</tt><i>Rmax</i><tt>] | </tt><i>NonASCIIDigit</i>
 227  *
 228  *   <dt><i>Digit</i>:
 229  *       <dd><tt>[0-</tt><i>Rmax</i><tt>] | </tt><i>NonASCIIDigit</i>
 230  *
 231  *   <dt><i>GroupedNumeral</i>:
 232  *       <dd><tt>(&nbsp;</tt><i>Non0Digit</i>
 233  *                   <i>Digit</i><tt>?
 234  *                   </tt><i>Digit</i><tt>?</tt>
 235  *       <dd>&nbsp;&nbsp;&nbsp;&nbsp;<tt>(&nbsp;</tt><i>LocalGroupSeparator</i>
 236  *                         <i>Digit</i>
 237  *                         <i>Digit</i>
 238  *                         <i>Digit</i><tt> )+ )</tt>
 239  *
 240  *   <dt><i>Numeral</i>:
 241  *       <dd><tt>( ( </tt><i>Digit</i><tt>+ )
 242  *               | </tt><i>GroupedNumeral</i><tt> )</tt>
 243  *
 244  *   <dt><a name="Integer-regex"><i>Integer</i>:</a>
 245  *       <dd><tt>( [-+]? ( </tt><i>Numeral</i><tt>
 246  *                               ) )</tt>
 247  *       <dd><tt>| </tt><i>LocalPositivePrefix</i> <i>Numeral</i>
 248  *                      <i>LocalPositiveSuffix</i>
 249  *       <dd><tt>| </tt><i>LocalNegativePrefix</i> <i>Numeral</i>
 250  *                 <i>LocalNegativeSuffix</i>
 251  *
 252  *   <dt><i>DecimalNumeral</i>:
 253  *       <dd><i>Numeral</i>
 254  *       <dd><tt>| </tt><i>Numeral</i>
 255  *                 <i>LocalDecimalSeparator</i>
 256  *                 <i>Digit</i><tt>*</tt>
 257  *       <dd><tt>| </tt><i>LocalDecimalSeparator</i>
 258  *                 <i>Digit</i><tt>+</tt>
 259  *
 260  *   <dt><i>Exponent</i>:
 261  *       <dd><tt>( [eE] [+-]? </tt><i>Digit</i><tt>+ )</tt>
 262  *
 263  *   <dt><a name="Decimal-regex"><i>Decimal</i>:</a>
 264  *       <dd><tt>( [-+]? </tt><i>DecimalNumeral</i>
 265  *                         <i>Exponent</i><tt>? )</tt>
 266  *       <dd><tt>| </tt><i>LocalPositivePrefix</i>
 267  *                 <i>DecimalNumeral</i>
 268  *                 <i>LocalPositiveSuffix</i>
 269  *                 <i>Exponent</i><tt>?</tt>
 270  *       <dd><tt>| </tt><i>LocalNegativePrefix</i>
 271  *                 <i>DecimalNumeral</i>
 272  *                 <i>LocalNegativeSuffix</i>
 273  *                 <i>Exponent</i><tt>?</tt>
 274  *
 275  *   <dt><i>HexFloat</i>:
 276  *       <dd><tt>[-+]? 0[xX][0-9a-fA-F]*\.[0-9a-fA-F]+
 277  *                 ([pP][-+]?[0-9]+)?</tt>
 278  *
 279  *   <dt><i>NonNumber</i>:
 280  *       <dd><tt>NaN
 281  *                          | </tt><i>LocalNan</i><tt>
 282  *                          | Infinity
 283  *                          | </tt><i>LocalInfinity</i>
 284  *
 285  *   <dt><i>SignedNonNumber</i>:
 286  *       <dd><tt>( [-+]? </tt><i>NonNumber</i><tt> )</tt>
 287  *       <dd><tt>| </tt><i>LocalPositivePrefix</i>
 288  *                 <i>NonNumber</i>
 289  *                 <i>LocalPositiveSuffix</i>
 290  *       <dd><tt>| </tt><i>LocalNegativePrefix</i>
 291  *                 <i>NonNumber</i>
 292  *                 <i>LocalNegativeSuffix</i>
 293  *
 294  *   <dt><a name="Float-regex"><i>Float</i></a>:
 295  *       <dd><i>Decimal</i>
 296  *           <tt>| </tt><i>HexFloat</i>
 297  *           <tt>| </tt><i>SignedNonNumber</i>
 298  *
 299  * </dl>
 300  * <p>Whitespace is not significant in the above regular expressions.
 301  *
 302  * @since   1.5
 303  */
 304 public final class Scanner implements Iterator<String>, Closeable {
 305 
 306     // Internal buffer used to hold input
 307     private CharBuffer buf;
 308 
 309     // Size of internal character buffer
 310     private static final int BUFFER_SIZE = 1024; // change to 1024;
 311 
 312     // The index into the buffer currently held by the Scanner
 313     private int position;
 314 
 315     // Internal matcher used for finding delimiters
 316     private Matcher matcher;
 317 


 504         floatPattern = Pattern.compile(decimal + "|" + hexFloat + "|" +
 505                                        signedNonNumber);
 506         decimalPattern = Pattern.compile(decimal);
 507     }
 508     private Pattern floatPattern() {
 509         if (floatPattern == null) {
 510             buildFloatAndDecimalPattern();
 511         }
 512         return floatPattern;
 513     }
 514     private Pattern decimalPattern() {
 515         if (decimalPattern == null) {
 516             buildFloatAndDecimalPattern();
 517         }
 518         return decimalPattern;
 519     }
 520 
 521     // Constructors
 522 
 523     /**
 524      * Constructs a <code>Scanner</code> that returns values scanned
 525      * from the specified source delimited by the specified pattern.
 526      *
 527      * @param source A character source implementing the Readable interface
 528      * @param pattern A delimiting pattern
 529      */
 530     private Scanner(Readable source, Pattern pattern) {
 531         assert source != null : "source should not be null";
 532         assert pattern != null : "pattern should not be null";
 533         this.source = source;
 534         delimPattern = pattern;
 535         buf = CharBuffer.allocate(BUFFER_SIZE);
 536         buf.limit(0);
 537         matcher = delimPattern.matcher(buf);
 538         matcher.useTransparentBounds(true);
 539         matcher.useAnchoringBounds(false);
 540         useLocale(Locale.getDefault(Locale.Category.FORMAT));
 541     }
 542 
 543     /**
 544      * Constructs a new <code>Scanner</code> that produces values scanned
 545      * from the specified source.
 546      *
 547      * @param  source A character source implementing the {@link Readable}
 548      *         interface
 549      */
 550     public Scanner(Readable source) {
 551         this(Objects.requireNonNull(source, "source"), WHITESPACE_PATTERN);
 552     }
 553 
 554     /**
 555      * Constructs a new <code>Scanner</code> that produces values scanned
 556      * from the specified input stream. Bytes from the stream are converted
 557      * into characters using the underlying platform's
 558      * {@linkplain java.nio.charset.Charset#defaultCharset() default charset}.
 559      *
 560      * @param  source An input stream to be scanned
 561      */
 562     public Scanner(InputStream source) {
 563         this(new InputStreamReader(source), WHITESPACE_PATTERN);
 564     }
 565 
 566     /**
 567      * Constructs a new <code>Scanner</code> that produces values scanned
 568      * from the specified input stream. Bytes from the stream are converted
 569      * into characters using the specified charset.
 570      *
 571      * @param  source An input stream to be scanned
 572      * @param charsetName The encoding type used to convert bytes from the
 573      *        stream into characters to be scanned
 574      * @throws IllegalArgumentException if the specified character set
 575      *         does not exist
 576      */
 577     public Scanner(InputStream source, String charsetName) {
 578         this(makeReadable(Objects.requireNonNull(source, "source"), toCharset(charsetName)),
 579              WHITESPACE_PATTERN);
 580     }
 581 
 582     /**
 583      * Returns a charset object for the given charset name.
 584      * @throws NullPointerException          is csn is null
 585      * @throws IllegalArgumentException      if the charset is not supported
 586      */
 587     private static Charset toCharset(String csn) {
 588         Objects.requireNonNull(csn, "charsetName");
 589         try {
 590             return Charset.forName(csn);
 591         } catch (IllegalCharsetNameException|UnsupportedCharsetException e) {
 592             // IllegalArgumentException should be thrown
 593             throw new IllegalArgumentException(e);
 594         }
 595     }
 596 
 597     private static Readable makeReadable(InputStream source, Charset charset) {
 598         return new InputStreamReader(source, charset);
 599     }
 600 
 601     /**
 602      * Constructs a new <code>Scanner</code> that produces values scanned
 603      * from the specified file. Bytes from the file are converted into
 604      * characters using the underlying platform's
 605      * {@linkplain java.nio.charset.Charset#defaultCharset() default charset}.
 606      *
 607      * @param  source A file to be scanned
 608      * @throws FileNotFoundException if source is not found
 609      */
 610     public Scanner(File source) throws FileNotFoundException {
 611         this((ReadableByteChannel)(new FileInputStream(source).getChannel()));
 612     }
 613 
 614     /**
 615      * Constructs a new <code>Scanner</code> that produces values scanned
 616      * from the specified file. Bytes from the file are converted into
 617      * characters using the specified charset.
 618      *
 619      * @param  source A file to be scanned
 620      * @param charsetName The encoding type used to convert bytes from the file
 621      *        into characters to be scanned
 622      * @throws FileNotFoundException if source is not found
 623      * @throws IllegalArgumentException if the specified encoding is
 624      *         not found
 625      */
 626     public Scanner(File source, String charsetName)
 627         throws FileNotFoundException
 628     {
 629         this(Objects.requireNonNull(source), toDecoder(charsetName));
 630     }
 631 
 632     private Scanner(File source, CharsetDecoder dec)
 633         throws FileNotFoundException
 634     {
 635         this(makeReadable((ReadableByteChannel)(new FileInputStream(source).getChannel()), dec));
 636     }
 637 
 638     private static CharsetDecoder toDecoder(String charsetName) {
 639         Objects.requireNonNull(charsetName, "charsetName");
 640         try {
 641             return Charset.forName(charsetName).newDecoder();
 642         } catch (IllegalCharsetNameException|UnsupportedCharsetException unused) {
 643             throw new IllegalArgumentException(charsetName);
 644         }
 645     }
 646 
 647     private static Readable makeReadable(ReadableByteChannel source,
 648                                          CharsetDecoder dec) {
 649         return Channels.newReader(source, dec, -1);
 650     }
 651 
 652     /**
 653      * Constructs a new <code>Scanner</code> that produces values scanned
 654      * from the specified file. Bytes from the file are converted into
 655      * characters using the underlying platform's
 656      * {@linkplain java.nio.charset.Charset#defaultCharset() default charset}.
 657      *
 658      * @param   source
 659      *          the path to the file to be scanned
 660      * @throws  IOException
 661      *          if an I/O error occurs opening source
 662      *
 663      * @since   1.7
 664      */
 665     public Scanner(Path source)
 666         throws IOException
 667     {
 668         this(Files.newInputStream(source));
 669     }
 670 
 671     /**
 672      * Constructs a new <code>Scanner</code> that produces values scanned
 673      * from the specified file. Bytes from the file are converted into
 674      * characters using the specified charset.
 675      *
 676      * @param   source
 677      *          the path to the file to be scanned
 678      * @param   charsetName
 679      *          The encoding type used to convert bytes from the file
 680      *          into characters to be scanned
 681      * @throws  IOException
 682      *          if an I/O error occurs opening source
 683      * @throws  IllegalArgumentException
 684      *          if the specified encoding is not found
 685      * @since   1.7
 686      */
 687     public Scanner(Path source, String charsetName) throws IOException {
 688         this(Objects.requireNonNull(source), toCharset(charsetName));
 689     }
 690 
 691     private Scanner(Path source, Charset charset)  throws IOException {
 692         this(makeReadable(Files.newInputStream(source), charset));
 693     }
 694 
 695     /**
 696      * Constructs a new <code>Scanner</code> that produces values scanned
 697      * from the specified string.
 698      *
 699      * @param  source A string to scan
 700      */
 701     public Scanner(String source) {
 702         this(new StringReader(source), WHITESPACE_PATTERN);
 703     }
 704 
 705     /**
 706      * Constructs a new <code>Scanner</code> that produces values scanned
 707      * from the specified channel. Bytes from the source are converted into
 708      * characters using the underlying platform's
 709      * {@linkplain java.nio.charset.Charset#defaultCharset() default charset}.
 710      *
 711      * @param  source A channel to scan
 712      */
 713     public Scanner(ReadableByteChannel source) {
 714         this(makeReadable(Objects.requireNonNull(source, "source")),
 715              WHITESPACE_PATTERN);
 716     }
 717 
 718     private static Readable makeReadable(ReadableByteChannel source) {
 719         return makeReadable(source, Charset.defaultCharset().newDecoder());
 720     }
 721 
 722     /**
 723      * Constructs a new <code>Scanner</code> that produces values scanned
 724      * from the specified channel. Bytes from the source are converted into
 725      * characters using the specified charset.
 726      *
 727      * @param  source A channel to scan
 728      * @param charsetName The encoding type used to convert bytes from the
 729      *        channel into characters to be scanned
 730      * @throws IllegalArgumentException if the specified character set
 731      *         does not exist
 732      */
 733     public Scanner(ReadableByteChannel source, String charsetName) {
 734         this(makeReadable(Objects.requireNonNull(source, "source"), toDecoder(charsetName)),
 735              WHITESPACE_PATTERN);
 736     }
 737 
 738     // Private primitives used to support scanning
 739 
 740     private void saveState() {
 741         savedScannerPosition = position;
 742     }
 743 


1060             return null;
1061 
1062         // Read more to find pattern
1063         needInput = true;
1064         return null;
1065     }
1066 
1067     // Throws if the scanner is closed
1068     private void ensureOpen() {
1069         if (closed)
1070             throw new IllegalStateException("Scanner closed");
1071     }
1072 
1073     // Public methods
1074 
1075     /**
1076      * Closes this scanner.
1077      *
1078      * <p> If this scanner has not yet been closed then if its underlying
1079      * {@linkplain java.lang.Readable readable} also implements the {@link
1080      * java.io.Closeable} interface then the readable's <tt>close</tt> method
1081      * will be invoked.  If this scanner is already closed then invoking this
1082      * method will have no effect.
1083      *
1084      * <p>Attempting to perform search operations after a scanner has
1085      * been closed will result in an {@link IllegalStateException}.
1086      *
1087      */
1088     public void close() {
1089         if (closed)
1090             return;
1091         if (source instanceof Closeable) {
1092             try {
1093                 ((Closeable)source).close();
1094             } catch (IOException ioe) {
1095                 lastException = ioe;
1096             }
1097         }
1098         sourceClosed = true;
1099         source = null;
1100         closed = true;
1101     }
1102 
1103     /**
1104      * Returns the <code>IOException</code> last thrown by this
1105      * <code>Scanner</code>'s underlying <code>Readable</code>. This method
1106      * returns <code>null</code> if no such exception exists.
1107      *
1108      * @return the last exception thrown by this scanner's readable
1109      */
1110     public IOException ioException() {
1111         return lastException;
1112     }
1113 
1114     /**
1115      * Returns the <code>Pattern</code> this <code>Scanner</code> is currently
1116      * using to match delimiters.
1117      *
1118      * @return this scanner's delimiting pattern.
1119      */
1120     public Pattern delimiter() {
1121         return delimPattern;
1122     }
1123 
1124     /**
1125      * Sets this scanner's delimiting pattern to the specified pattern.
1126      *
1127      * @param pattern A delimiting pattern
1128      * @return this scanner
1129      */
1130     public Scanner useDelimiter(Pattern pattern) {
1131         delimPattern = pattern;
1132         return this;
1133     }
1134 
1135     /**
1136      * Sets this scanner's delimiting pattern to a pattern constructed from
1137      * the specified <code>String</code>.
1138      *
1139      * <p> An invocation of this method of the form
1140      * <tt>useDelimiter(pattern)</tt> behaves in exactly the same way as the
1141      * invocation <tt>useDelimiter(Pattern.compile(pattern))</tt>.
1142      *
1143      * <p> Invoking the {@link #reset} method will set the scanner's delimiter
1144      * to the <a href= "#default-delimiter">default</a>.
1145      *
1146      * @param pattern A string specifying a delimiting pattern
1147      * @return this scanner
1148      */
1149     public Scanner useDelimiter(String pattern) {
1150         delimPattern = patternCache.forName(pattern);
1151         return this;
1152     }
1153 
1154     /**
1155      * Returns this scanner's locale.
1156      *
1157      * <p>A scanner's locale affects many elements of its default
1158      * primitive matching regular expressions; see
1159      * <a href= "#localized-numbers">localized numbers</a> above.
1160      *
1161      * @return this scanner's locale


1219     /**
1220      * Returns this scanner's default radix.
1221      *
1222      * <p>A scanner's radix affects elements of its default
1223      * number matching regular expressions; see
1224      * <a href= "#localized-numbers">localized numbers</a> above.
1225      *
1226      * @return the default radix of this scanner
1227      */
1228     public int radix() {
1229         return this.defaultRadix;
1230     }
1231 
1232     /**
1233      * Sets this scanner's default radix to the specified radix.
1234      *
1235      * <p>A scanner's radix affects elements of its default
1236      * number matching regular expressions; see
1237      * <a href= "#localized-numbers">localized numbers</a> above.
1238      *
1239      * <p>If the radix is less than <code>Character.MIN_RADIX</code>
1240      * or greater than <code>Character.MAX_RADIX</code>, then an
1241      * <code>IllegalArgumentException</code> is thrown.
1242      *
1243      * <p>Invoking the {@link #reset} method will set the scanner's radix to
1244      * <code>10</code>.
1245      *
1246      * @param radix The radix to use when scanning numbers
1247      * @return this scanner
1248      * @throws IllegalArgumentException if radix is out of range
1249      */
1250     public Scanner useRadix(int radix) {
1251         if ((radix < Character.MIN_RADIX) || (radix > Character.MAX_RADIX))
1252             throw new IllegalArgumentException("radix:"+radix);
1253 
1254         if (this.defaultRadix == radix)
1255             return this;
1256         this.defaultRadix = radix;
1257         // Force rebuilding and recompilation of radix dependent patterns
1258         integerPattern = null;
1259         return this;
1260     }
1261 
1262     // The next operation should occur in the specified radix but
1263     // the default is left untouched.
1264     private void setRadix(int radix) {
1265         if (this.radix != radix) {
1266             // Force rebuilding and recompilation of radix dependent patterns
1267             integerPattern = null;
1268             this.radix = radix;
1269         }
1270     }
1271 
1272     /**
1273      * Returns the match result of the last scanning operation performed
1274      * by this scanner. This method throws <code>IllegalStateException</code>
1275      * if no match has been performed, or if the last match was
1276      * not successful.
1277      *
1278      * <p>The various <code>next</code>methods of <code>Scanner</code>
1279      * make a match result available if they complete without throwing an
1280      * exception. For instance, after an invocation of the {@link #nextInt}
1281      * method that returned an int, this method returns a
1282      * <code>MatchResult</code> for the search of the
1283      * <a href="#Integer-regex"><i>Integer</i></a> regular expression
1284      * defined above. Similarly the {@link #findInLine},
1285      * {@link #findWithinHorizon}, and {@link #skip} methods will make a
1286      * match available if they succeed.
1287      *
1288      * @return a match result for the last match operation
1289      * @throws IllegalStateException  If no match result is available
1290      */
1291     public MatchResult match() {
1292         if (!matchValid)
1293             throw new IllegalStateException("No match result available");
1294         return matcher.toMatchResult();
1295     }
1296 
1297     /**
1298      * <p>Returns the string representation of this <code>Scanner</code>. The
1299      * string representation of a <code>Scanner</code> contains information
1300      * that may be useful for debugging. The exact format is unspecified.
1301      *
1302      * @return  The string representation of this scanner
1303      */
1304     public String toString() {
1305         StringBuilder sb = new StringBuilder();
1306         sb.append("java.util.Scanner");
1307         sb.append("[delimiters=" + delimPattern + "]");
1308         sb.append("[position=" + position + "]");
1309         sb.append("[match valid=" + matchValid + "]");
1310         sb.append("[need input=" + needInput + "]");
1311         sb.append("[source closed=" + sourceClosed + "]");
1312         sb.append("[skipped=" + skipped + "]");
1313         sb.append("[group separator=" + groupSeparator + "]");
1314         sb.append("[decimal separator=" + decimalSeparator + "]");
1315         sb.append("[positive prefix=" + positivePrefix + "]");
1316         sb.append("[negative prefix=" + negativePrefix + "]");
1317         sb.append("[positive suffix=" + positiveSuffix + "]");
1318         sb.append("[negative suffix=" + negativeSuffix + "]");
1319         sb.append("[NaN string=" + nanString + "]");


1330      * @throws IllegalStateException if this scanner is closed
1331      * @see java.util.Iterator
1332      */
1333     public boolean hasNext() {
1334         ensureOpen();
1335         saveState();
1336         while (!sourceClosed) {
1337             if (hasTokenInBuffer())
1338                 return revertState(true);
1339             readInput();
1340         }
1341         boolean result = hasTokenInBuffer();
1342         return revertState(result);
1343     }
1344 
1345     /**
1346      * Finds and returns the next complete token from this scanner.
1347      * A complete token is preceded and followed by input that matches
1348      * the delimiter pattern. This method may block while waiting for input
1349      * to scan, even if a previous invocation of {@link #hasNext} returned
1350      * <code>true</code>.
1351      *
1352      * @return the next token
1353      * @throws NoSuchElementException if no more tokens are available
1354      * @throws IllegalStateException if this scanner is closed
1355      * @see java.util.Iterator
1356      */
1357     public String next() {
1358         ensureOpen();
1359         clearCaches();
1360 
1361         while (true) {
1362             String token = getCompleteTokenInBuffer(null);
1363             if (token != null) {
1364                 matchValid = true;
1365                 skipped = false;
1366                 return token;
1367             }
1368             if (needInput)
1369                 readInput();
1370             else
1371                 throwFor();
1372         }
1373     }
1374 
1375     /**
1376      * The remove operation is not supported by this implementation of
1377      * <code>Iterator</code>.
1378      *
1379      * @throws UnsupportedOperationException if this method is invoked.
1380      * @see java.util.Iterator
1381      */
1382     public void remove() {
1383         throw new UnsupportedOperationException();
1384     }
1385 
1386     /**
1387      * Returns true if the next token matches the pattern constructed from the
1388      * specified string. The scanner does not advance past any input.
1389      *
1390      * <p> An invocation of this method of the form <tt>hasNext(pattern)</tt>
1391      * behaves in exactly the same way as the invocation
1392      * <tt>hasNext(Pattern.compile(pattern))</tt>.
1393      *
1394      * @param pattern a string specifying the pattern to scan
1395      * @return true if and only if this scanner has another token matching
1396      *         the specified pattern
1397      * @throws IllegalStateException if this scanner is closed
1398      */
1399     public boolean hasNext(String pattern)  {
1400         return hasNext(patternCache.forName(pattern));
1401     }
1402 
1403     /**
1404      * Returns the next token if it matches the pattern constructed from the
1405      * specified string.  If the match is successful, the scanner advances
1406      * past the input that matched the pattern.
1407      *
1408      * <p> An invocation of this method of the form <tt>next(pattern)</tt>
1409      * behaves in exactly the same way as the invocation
1410      * <tt>next(Pattern.compile(pattern))</tt>.
1411      *
1412      * @param pattern a string specifying the pattern to scan
1413      * @return the next token
1414      * @throws NoSuchElementException if no such tokens are available
1415      * @throws IllegalStateException if this scanner is closed
1416      */
1417     public String next(String pattern)  {
1418         return next(patternCache.forName(pattern));
1419     }
1420 
1421     /**
1422      * Returns true if the next complete token matches the specified pattern.
1423      * A complete token is prefixed and postfixed by input that matches
1424      * the delimiter pattern. This method may block while waiting for input.
1425      * The scanner does not advance past any input.
1426      *
1427      * @param pattern the pattern to scan for
1428      * @return true if and only if this scanner has another token matching
1429      *         the specified pattern
1430      * @throws IllegalStateException if this scanner is closed


1435             throw new NullPointerException();
1436         hasNextPattern = null;
1437         saveState();
1438 
1439         while (true) {
1440             if (getCompleteTokenInBuffer(pattern) != null) {
1441                 matchValid = true;
1442                 cacheResult();
1443                 return revertState(true);
1444             }
1445             if (needInput)
1446                 readInput();
1447             else
1448                 return revertState(false);
1449         }
1450     }
1451 
1452     /**
1453      * Returns the next token if it matches the specified pattern. This
1454      * method may block while waiting for input to scan, even if a previous
1455      * invocation of {@link #hasNext(Pattern)} returned <code>true</code>.
1456      * If the match is successful, the scanner advances past the input that
1457      * matched the pattern.
1458      *
1459      * @param pattern the pattern to scan for
1460      * @return the next token
1461      * @throws NoSuchElementException if no more tokens are available
1462      * @throws IllegalStateException if this scanner is closed
1463      */
1464     public String next(Pattern pattern) {
1465         ensureOpen();
1466         if (pattern == null)
1467             throw new NullPointerException();
1468 
1469         // Did we already find this pattern?
1470         if (hasNextPattern == pattern)
1471             return getCachedResult();
1472         clearCaches();
1473 
1474         // Search for the pattern
1475         while (true) {


1537 
1538         String result = findWithinHorizon(linePattern, 0);
1539         if (result == null)
1540             throw new NoSuchElementException("No line found");
1541         MatchResult mr = this.match();
1542         String lineSep = mr.group(1);
1543         if (lineSep != null)
1544             result = result.substring(0, result.length() - lineSep.length());
1545         if (result == null)
1546             throw new NoSuchElementException();
1547         else
1548             return result;
1549     }
1550 
1551     // Public methods that ignore delimiters
1552 
1553     /**
1554      * Attempts to find the next occurrence of a pattern constructed from the
1555      * specified string, ignoring delimiters.
1556      *
1557      * <p>An invocation of this method of the form <tt>findInLine(pattern)</tt>
1558      * behaves in exactly the same way as the invocation
1559      * <tt>findInLine(Pattern.compile(pattern))</tt>.
1560      *
1561      * @param pattern a string specifying the pattern to search for
1562      * @return the text that matched the specified pattern
1563      * @throws IllegalStateException if this scanner is closed
1564      */
1565     public String findInLine(String pattern) {
1566         return findInLine(patternCache.forName(pattern));
1567     }
1568 
1569     /**
1570      * Attempts to find the next occurrence of the specified pattern ignoring
1571      * delimiters. If the pattern is found before the next line separator, the
1572      * scanner advances past the input that matched and returns the string that
1573      * matched the pattern.
1574      * If no such pattern is detected in the input up to the next line
1575      * separator, then <code>null</code> is returned and the scanner's
1576      * position is unchanged. This method may block waiting for input that
1577      * matches the pattern.
1578      *
1579      * <p>Since this method continues to search through the input looking
1580      * for the specified pattern, it may buffer all of the input searching for
1581      * the desired token if no line separators are present.
1582      *
1583      * @param pattern the pattern to scan for
1584      * @return the text that matched the specified pattern
1585      * @throws IllegalStateException if this scanner is closed
1586      */
1587     public String findInLine(Pattern pattern) {
1588         ensureOpen();
1589         if (pattern == null)
1590             throw new NullPointerException();
1591         clearCaches();
1592         // Expand buffer to include the next newline or end of input
1593         int endPosition = 0;
1594         saveState();
1595         while (true) {


1604                 endPosition = buf.limit();
1605                 break; // up to end of input
1606             }
1607         }
1608         revertState();
1609         int horizonForLine = endPosition - position;
1610         // If there is nothing between the current pos and the next
1611         // newline simply return null, invoking findWithinHorizon
1612         // with "horizon=0" will scan beyond the line bound.
1613         if (horizonForLine == 0)
1614             return null;
1615         // Search for the pattern
1616         return findWithinHorizon(pattern, horizonForLine);
1617     }
1618 
1619     /**
1620      * Attempts to find the next occurrence of a pattern constructed from the
1621      * specified string, ignoring delimiters.
1622      *
1623      * <p>An invocation of this method of the form
1624      * <tt>findWithinHorizon(pattern)</tt> behaves in exactly the same way as
1625      * the invocation
1626      * <tt>findWithinHorizon(Pattern.compile(pattern, horizon))</tt>.
1627      *
1628      * @param pattern a string specifying the pattern to search for
1629      * @param horizon the search horizon
1630      * @return the text that matched the specified pattern
1631      * @throws IllegalStateException if this scanner is closed
1632      * @throws IllegalArgumentException if horizon is negative
1633      */
1634     public String findWithinHorizon(String pattern, int horizon) {
1635         return findWithinHorizon(patternCache.forName(pattern), horizon);
1636     }
1637 
1638     /**
1639      * Attempts to find the next occurrence of the specified pattern.
1640      *
1641      * <p>This method searches through the input up to the specified
1642      * search horizon, ignoring delimiters. If the pattern is found the
1643      * scanner advances past the input that matched and returns the string
1644      * that matched the pattern. If no such pattern is detected then the
1645      * null is returned and the scanner's position remains unchanged. This
1646      * method may block waiting for input that matches the pattern.
1647      *
1648      * <p>A scanner will never search more than <code>horizon</code> code
1649      * points beyond its current position. Note that a match may be clipped
1650      * by the horizon; that is, an arbitrary match result may have been
1651      * different if the horizon had been larger. The scanner treats the
1652      * horizon as a transparent, non-anchoring bound (see {@link
1653      * Matcher#useTransparentBounds} and {@link Matcher#useAnchoringBounds}).
1654      *
1655      * <p>If horizon is <code>0</code>, then the horizon is ignored and
1656      * this method continues to search through the input looking for the
1657      * specified pattern without bound. In this case it may buffer all of
1658      * the input searching for the pattern.
1659      *
1660      * <p>If horizon is negative, then an IllegalArgumentException is
1661      * thrown.
1662      *
1663      * @param pattern the pattern to scan for
1664      * @param horizon the search horizon
1665      * @return the text that matched the specified pattern
1666      * @throws IllegalStateException if this scanner is closed
1667      * @throws IllegalArgumentException if horizon is negative
1668      */
1669     public String findWithinHorizon(Pattern pattern, int horizon) {
1670         ensureOpen();
1671         if (pattern == null)
1672             throw new NullPointerException();
1673         if (horizon < 0)
1674             throw new IllegalArgumentException("horizon < 0");
1675         clearCaches();


1679             String token = findPatternInBuffer(pattern, horizon);
1680             if (token != null) {
1681                 matchValid = true;
1682                 return token;
1683             }
1684             if (needInput)
1685                 readInput();
1686             else
1687                 break; // up to end of input
1688         }
1689         return null;
1690     }
1691 
1692     /**
1693      * Skips input that matches the specified pattern, ignoring delimiters.
1694      * This method will skip input if an anchored match of the specified
1695      * pattern succeeds.
1696      *
1697      * <p>If a match to the specified pattern is not found at the
1698      * current position, then no input is skipped and a
1699      * <tt>NoSuchElementException</tt> is thrown.
1700      *
1701      * <p>Since this method seeks to match the specified pattern starting at
1702      * the scanner's current position, patterns that can match a lot of
1703      * input (".*", for example) may cause the scanner to buffer a large
1704      * amount of input.
1705      *
1706      * <p>Note that it is possible to skip something without risking a
1707      * <code>NoSuchElementException</code> by using a pattern that can
1708      * match nothing, e.g., <code>sc.skip("[ \t]*")</code>.
1709      *
1710      * @param pattern a string specifying the pattern to skip over
1711      * @return this scanner
1712      * @throws NoSuchElementException if the specified pattern is not found
1713      * @throws IllegalStateException if this scanner is closed
1714      */
1715     public Scanner skip(Pattern pattern) {
1716         ensureOpen();
1717         if (pattern == null)
1718             throw new NullPointerException();
1719         clearCaches();
1720 
1721         // Search for the pattern
1722         while (true) {
1723             String token = matchPatternInBuffer(pattern);
1724             if (token != null) {
1725                 matchValid = true;
1726                 position = matcher.end();
1727                 return this;
1728             }
1729             if (needInput)
1730                 readInput();
1731             else
1732                 throw new NoSuchElementException();
1733         }
1734     }
1735 
1736     /**
1737      * Skips input that matches a pattern constructed from the specified
1738      * string.
1739      *
1740      * <p> An invocation of this method of the form <tt>skip(pattern)</tt>
1741      * behaves in exactly the same way as the invocation
1742      * <tt>skip(Pattern.compile(pattern))</tt>.
1743      *
1744      * @param pattern a string specifying the pattern to skip over
1745      * @return this scanner
1746      * @throws IllegalStateException if this scanner is closed
1747      */
1748     public Scanner skip(String pattern) {
1749         return skip(patternCache.forName(pattern));
1750     }
1751 
1752     // Convenience methods for scanning primitives
1753 
1754     /**
1755      * Returns true if the next token in this scanner's input can be
1756      * interpreted as a boolean value using a case insensitive pattern
1757      * created from the string "true|false".  The scanner does not
1758      * advance past the input that matched.
1759      *
1760      * @return true if and only if this scanner's next token is a valid
1761      *         boolean value
1762      * @throws IllegalStateException if this scanner is closed
1763      */
1764     public boolean hasNextBoolean()  {
1765         return hasNext(boolPattern());
1766     }
1767 
1768     /**
1769      * Scans the next token of the input into a boolean value and returns
1770      * that value. This method will throw <code>InputMismatchException</code>
1771      * if the next token cannot be translated into a valid boolean value.
1772      * If the match is successful, the scanner advances past the input that
1773      * matched.
1774      *
1775      * @return the boolean scanned from the input
1776      * @throws InputMismatchException if the next token is not a valid boolean
1777      * @throws NoSuchElementException if input is exhausted
1778      * @throws IllegalStateException if this scanner is closed
1779      */
1780     public boolean nextBoolean()  {
1781         clearCaches();
1782         return Boolean.parseBoolean(next(boolPattern()));
1783     }
1784 
1785     /**
1786      * Returns true if the next token in this scanner's input can be
1787      * interpreted as a byte value in the default radix using the
1788      * {@link #nextByte} method. The scanner does not advance past any input.
1789      *
1790      * @return true if and only if this scanner's next token is a valid


1805      *         byte value
1806      * @throws IllegalStateException if this scanner is closed
1807      */
1808     public boolean hasNextByte(int radix) {
1809         setRadix(radix);
1810         boolean result = hasNext(integerPattern());
1811         if (result) { // Cache it
1812             try {
1813                 String s = (matcher.group(SIMPLE_GROUP_INDEX) == null) ?
1814                     processIntegerToken(hasNextResult) :
1815                     hasNextResult;
1816                 typeCache = Byte.parseByte(s, radix);
1817             } catch (NumberFormatException nfe) {
1818                 result = false;
1819             }
1820         }
1821         return result;
1822     }
1823 
1824     /**
1825      * Scans the next token of the input as a <tt>byte</tt>.
1826      *
1827      * <p> An invocation of this method of the form
1828      * <tt>nextByte()</tt> behaves in exactly the same way as the
1829      * invocation <tt>nextByte(radix)</tt>, where <code>radix</code>
1830      * is the default radix of this scanner.
1831      *
1832      * @return the <tt>byte</tt> scanned from the input
1833      * @throws InputMismatchException
1834      *         if the next token does not match the <i>Integer</i>
1835      *         regular expression, or is out of range
1836      * @throws NoSuchElementException if input is exhausted
1837      * @throws IllegalStateException if this scanner is closed
1838      */
1839     public byte nextByte() {
1840          return nextByte(defaultRadix);
1841     }
1842 
1843     /**
1844      * Scans the next token of the input as a <tt>byte</tt>.
1845      * This method will throw <code>InputMismatchException</code>
1846      * if the next token cannot be translated into a valid byte value as
1847      * described below. If the translation is successful, the scanner advances
1848      * past the input that matched.
1849      *
1850      * <p> If the next token matches the <a
1851      * href="#Integer-regex"><i>Integer</i></a> regular expression defined
1852      * above then the token is converted into a <tt>byte</tt> value as if by
1853      * removing all locale specific prefixes, group separators, and locale
1854      * specific suffixes, then mapping non-ASCII digits into ASCII
1855      * digits via {@link Character#digit Character.digit}, prepending a
1856      * negative sign (-) if the locale specific negative prefixes and suffixes
1857      * were present, and passing the resulting string to
1858      * {@link Byte#parseByte(String, int) Byte.parseByte} with the
1859      * specified radix.
1860      *
1861      * @param radix the radix used to interpret the token as a byte value
1862      * @return the <tt>byte</tt> scanned from the input
1863      * @throws InputMismatchException
1864      *         if the next token does not match the <i>Integer</i>
1865      *         regular expression, or is out of range
1866      * @throws NoSuchElementException if input is exhausted
1867      * @throws IllegalStateException if this scanner is closed
1868      */
1869     public byte nextByte(int radix) {
1870         // Check cached result
1871         if ((typeCache != null) && (typeCache instanceof Byte)
1872             && this.radix == radix) {
1873             byte val = ((Byte)typeCache).byteValue();
1874             useTypeCache();
1875             return val;
1876         }
1877         setRadix(radix);
1878         clearCaches();
1879         // Search for next byte
1880         try {
1881             String s = next(integerPattern());
1882             if (matcher.group(SIMPLE_GROUP_INDEX) == null)


1911      *         short value in the specified radix
1912      * @throws IllegalStateException if this scanner is closed
1913      */
1914     public boolean hasNextShort(int radix) {
1915         setRadix(radix);
1916         boolean result = hasNext(integerPattern());
1917         if (result) { // Cache it
1918             try {
1919                 String s = (matcher.group(SIMPLE_GROUP_INDEX) == null) ?
1920                     processIntegerToken(hasNextResult) :
1921                     hasNextResult;
1922                 typeCache = Short.parseShort(s, radix);
1923             } catch (NumberFormatException nfe) {
1924                 result = false;
1925             }
1926         }
1927         return result;
1928     }
1929 
1930     /**
1931      * Scans the next token of the input as a <tt>short</tt>.
1932      *
1933      * <p> An invocation of this method of the form
1934      * <tt>nextShort()</tt> behaves in exactly the same way as the
1935      * invocation <tt>nextShort(radix)</tt>, where <code>radix</code>
1936      * is the default radix of this scanner.
1937      *
1938      * @return the <tt>short</tt> scanned from the input
1939      * @throws InputMismatchException
1940      *         if the next token does not match the <i>Integer</i>
1941      *         regular expression, or is out of range
1942      * @throws NoSuchElementException if input is exhausted
1943      * @throws IllegalStateException if this scanner is closed
1944      */
1945     public short nextShort() {
1946         return nextShort(defaultRadix);
1947     }
1948 
1949     /**
1950      * Scans the next token of the input as a <tt>short</tt>.
1951      * This method will throw <code>InputMismatchException</code>
1952      * if the next token cannot be translated into a valid short value as
1953      * described below. If the translation is successful, the scanner advances
1954      * past the input that matched.
1955      *
1956      * <p> If the next token matches the <a
1957      * href="#Integer-regex"><i>Integer</i></a> regular expression defined
1958      * above then the token is converted into a <tt>short</tt> value as if by
1959      * removing all locale specific prefixes, group separators, and locale
1960      * specific suffixes, then mapping non-ASCII digits into ASCII
1961      * digits via {@link Character#digit Character.digit}, prepending a
1962      * negative sign (-) if the locale specific negative prefixes and suffixes
1963      * were present, and passing the resulting string to
1964      * {@link Short#parseShort(String, int) Short.parseShort} with the
1965      * specified radix.
1966      *
1967      * @param radix the radix used to interpret the token as a short value
1968      * @return the <tt>short</tt> scanned from the input
1969      * @throws InputMismatchException
1970      *         if the next token does not match the <i>Integer</i>
1971      *         regular expression, or is out of range
1972      * @throws NoSuchElementException if input is exhausted
1973      * @throws IllegalStateException if this scanner is closed
1974      */
1975     public short nextShort(int radix) {
1976         // Check cached result
1977         if ((typeCache != null) && (typeCache instanceof Short)
1978             && this.radix == radix) {
1979             short val = ((Short)typeCache).shortValue();
1980             useTypeCache();
1981             return val;
1982         }
1983         setRadix(radix);
1984         clearCaches();
1985         // Search for next short
1986         try {
1987             String s = next(integerPattern());
1988             if (matcher.group(SIMPLE_GROUP_INDEX) == null)


2041     private String processIntegerToken(String token) {
2042         String result = token.replaceAll(""+groupSeparator, "");
2043         boolean isNegative = false;
2044         int preLen = negativePrefix.length();
2045         if ((preLen > 0) && result.startsWith(negativePrefix)) {
2046             isNegative = true;
2047             result = result.substring(preLen);
2048         }
2049         int sufLen = negativeSuffix.length();
2050         if ((sufLen > 0) && result.endsWith(negativeSuffix)) {
2051             isNegative = true;
2052             result = result.substring(result.length() - sufLen,
2053                                       result.length());
2054         }
2055         if (isNegative)
2056             result = "-" + result;
2057         return result;
2058     }
2059 
2060     /**
2061      * Scans the next token of the input as an <tt>int</tt>.
2062      *
2063      * <p> An invocation of this method of the form
2064      * <tt>nextInt()</tt> behaves in exactly the same way as the
2065      * invocation <tt>nextInt(radix)</tt>, where <code>radix</code>
2066      * is the default radix of this scanner.
2067      *
2068      * @return the <tt>int</tt> scanned from the input
2069      * @throws InputMismatchException
2070      *         if the next token does not match the <i>Integer</i>
2071      *         regular expression, or is out of range
2072      * @throws NoSuchElementException if input is exhausted
2073      * @throws IllegalStateException if this scanner is closed
2074      */
2075     public int nextInt() {
2076         return nextInt(defaultRadix);
2077     }
2078 
2079     /**
2080      * Scans the next token of the input as an <tt>int</tt>.
2081      * This method will throw <code>InputMismatchException</code>
2082      * if the next token cannot be translated into a valid int value as
2083      * described below. If the translation is successful, the scanner advances
2084      * past the input that matched.
2085      *
2086      * <p> If the next token matches the <a
2087      * href="#Integer-regex"><i>Integer</i></a> regular expression defined
2088      * above then the token is converted into an <tt>int</tt> value as if by
2089      * removing all locale specific prefixes, group separators, and locale
2090      * specific suffixes, then mapping non-ASCII digits into ASCII
2091      * digits via {@link Character#digit Character.digit}, prepending a
2092      * negative sign (-) if the locale specific negative prefixes and suffixes
2093      * were present, and passing the resulting string to
2094      * {@link Integer#parseInt(String, int) Integer.parseInt} with the
2095      * specified radix.
2096      *
2097      * @param radix the radix used to interpret the token as an int value
2098      * @return the <tt>int</tt> scanned from the input
2099      * @throws InputMismatchException
2100      *         if the next token does not match the <i>Integer</i>
2101      *         regular expression, or is out of range
2102      * @throws NoSuchElementException if input is exhausted
2103      * @throws IllegalStateException if this scanner is closed
2104      */
2105     public int nextInt(int radix) {
2106         // Check cached result
2107         if ((typeCache != null) && (typeCache instanceof Integer)
2108             && this.radix == radix) {
2109             int val = ((Integer)typeCache).intValue();
2110             useTypeCache();
2111             return val;
2112         }
2113         setRadix(radix);
2114         clearCaches();
2115         // Search for next int
2116         try {
2117             String s = next(integerPattern());
2118             if (matcher.group(SIMPLE_GROUP_INDEX) == null)


2147      *         long value
2148      * @throws IllegalStateException if this scanner is closed
2149      */
2150     public boolean hasNextLong(int radix) {
2151         setRadix(radix);
2152         boolean result = hasNext(integerPattern());
2153         if (result) { // Cache it
2154             try {
2155                 String s = (matcher.group(SIMPLE_GROUP_INDEX) == null) ?
2156                     processIntegerToken(hasNextResult) :
2157                     hasNextResult;
2158                 typeCache = Long.parseLong(s, radix);
2159             } catch (NumberFormatException nfe) {
2160                 result = false;
2161             }
2162         }
2163         return result;
2164     }
2165 
2166     /**
2167      * Scans the next token of the input as a <tt>long</tt>.
2168      *
2169      * <p> An invocation of this method of the form
2170      * <tt>nextLong()</tt> behaves in exactly the same way as the
2171      * invocation <tt>nextLong(radix)</tt>, where <code>radix</code>
2172      * is the default radix of this scanner.
2173      *
2174      * @return the <tt>long</tt> scanned from the input
2175      * @throws InputMismatchException
2176      *         if the next token does not match the <i>Integer</i>
2177      *         regular expression, or is out of range
2178      * @throws NoSuchElementException if input is exhausted
2179      * @throws IllegalStateException if this scanner is closed
2180      */
2181     public long nextLong() {
2182         return nextLong(defaultRadix);
2183     }
2184 
2185     /**
2186      * Scans the next token of the input as a <tt>long</tt>.
2187      * This method will throw <code>InputMismatchException</code>
2188      * if the next token cannot be translated into a valid long value as
2189      * described below. If the translation is successful, the scanner advances
2190      * past the input that matched.
2191      *
2192      * <p> If the next token matches the <a
2193      * href="#Integer-regex"><i>Integer</i></a> regular expression defined
2194      * above then the token is converted into a <tt>long</tt> value as if by
2195      * removing all locale specific prefixes, group separators, and locale
2196      * specific suffixes, then mapping non-ASCII digits into ASCII
2197      * digits via {@link Character#digit Character.digit}, prepending a
2198      * negative sign (-) if the locale specific negative prefixes and suffixes
2199      * were present, and passing the resulting string to
2200      * {@link Long#parseLong(String, int) Long.parseLong} with the
2201      * specified radix.
2202      *
2203      * @param radix the radix used to interpret the token as an int value
2204      * @return the <tt>long</tt> scanned from the input
2205      * @throws InputMismatchException
2206      *         if the next token does not match the <i>Integer</i>
2207      *         regular expression, or is out of range
2208      * @throws NoSuchElementException if input is exhausted
2209      * @throws IllegalStateException if this scanner is closed
2210      */
2211     public long nextLong(int radix) {
2212         // Check cached result
2213         if ((typeCache != null) && (typeCache instanceof Long)
2214             && this.radix == radix) {
2215             long val = ((Long)typeCache).longValue();
2216             useTypeCache();
2217             return val;
2218         }
2219         setRadix(radix);
2220         clearCaches();
2221         try {
2222             String s = next(integerPattern());
2223             if (matcher.group(SIMPLE_GROUP_INDEX) == null)
2224                 s = processIntegerToken(s);


2289      *
2290      * @return true if and only if this scanner's next token is a valid
2291      *         float value
2292      * @throws IllegalStateException if this scanner is closed
2293      */
2294     public boolean hasNextFloat() {
2295         setRadix(10);
2296         boolean result = hasNext(floatPattern());
2297         if (result) { // Cache it
2298             try {
2299                 String s = processFloatToken(hasNextResult);
2300                 typeCache = Float.valueOf(Float.parseFloat(s));
2301             } catch (NumberFormatException nfe) {
2302                 result = false;
2303             }
2304         }
2305         return result;
2306     }
2307 
2308     /**
2309      * Scans the next token of the input as a <tt>float</tt>.
2310      * This method will throw <code>InputMismatchException</code>
2311      * if the next token cannot be translated into a valid float value as
2312      * described below. If the translation is successful, the scanner advances
2313      * past the input that matched.
2314      *
2315      * <p> If the next token matches the <a
2316      * href="#Float-regex"><i>Float</i></a> regular expression defined above
2317      * then the token is converted into a <tt>float</tt> value as if by
2318      * removing all locale specific prefixes, group separators, and locale
2319      * specific suffixes, then mapping non-ASCII digits into ASCII
2320      * digits via {@link Character#digit Character.digit}, prepending a
2321      * negative sign (-) if the locale specific negative prefixes and suffixes
2322      * were present, and passing the resulting string to
2323      * {@link Float#parseFloat Float.parseFloat}. If the token matches
2324      * the localized NaN or infinity strings, then either "Nan" or "Infinity"
2325      * is passed to {@link Float#parseFloat(String) Float.parseFloat} as
2326      * appropriate.
2327      *
2328      * @return the <tt>float</tt> scanned from the input
2329      * @throws InputMismatchException
2330      *         if the next token does not match the <i>Float</i>
2331      *         regular expression, or is out of range
2332      * @throws NoSuchElementException if input is exhausted
2333      * @throws IllegalStateException if this scanner is closed
2334      */
2335     public float nextFloat() {
2336         // Check cached result
2337         if ((typeCache != null) && (typeCache instanceof Float)) {
2338             float val = ((Float)typeCache).floatValue();
2339             useTypeCache();
2340             return val;
2341         }
2342         setRadix(10);
2343         clearCaches();
2344         try {
2345             return Float.parseFloat(processFloatToken(next(floatPattern())));
2346         } catch (NumberFormatException nfe) {
2347             position = matcher.start(); // don't skip bad token
2348             throw new InputMismatchException(nfe.getMessage());


2356      *
2357      * @return true if and only if this scanner's next token is a valid
2358      *         double value
2359      * @throws IllegalStateException if this scanner is closed
2360      */
2361     public boolean hasNextDouble() {
2362         setRadix(10);
2363         boolean result = hasNext(floatPattern());
2364         if (result) { // Cache it
2365             try {
2366                 String s = processFloatToken(hasNextResult);
2367                 typeCache = Double.valueOf(Double.parseDouble(s));
2368             } catch (NumberFormatException nfe) {
2369                 result = false;
2370             }
2371         }
2372         return result;
2373     }
2374 
2375     /**
2376      * Scans the next token of the input as a <tt>double</tt>.
2377      * This method will throw <code>InputMismatchException</code>
2378      * if the next token cannot be translated into a valid double value.
2379      * If the translation is successful, the scanner advances past the input
2380      * that matched.
2381      *
2382      * <p> If the next token matches the <a
2383      * href="#Float-regex"><i>Float</i></a> regular expression defined above
2384      * then the token is converted into a <tt>double</tt> value as if by
2385      * removing all locale specific prefixes, group separators, and locale
2386      * specific suffixes, then mapping non-ASCII digits into ASCII
2387      * digits via {@link Character#digit Character.digit}, prepending a
2388      * negative sign (-) if the locale specific negative prefixes and suffixes
2389      * were present, and passing the resulting string to
2390      * {@link Double#parseDouble Double.parseDouble}. If the token matches
2391      * the localized NaN or infinity strings, then either "Nan" or "Infinity"
2392      * is passed to {@link Double#parseDouble(String) Double.parseDouble} as
2393      * appropriate.
2394      *
2395      * @return the <tt>double</tt> scanned from the input
2396      * @throws InputMismatchException
2397      *         if the next token does not match the <i>Float</i>
2398      *         regular expression, or is out of range
2399      * @throws NoSuchElementException if the input is exhausted
2400      * @throws IllegalStateException if this scanner is closed
2401      */
2402     public double nextDouble() {
2403         // Check cached result
2404         if ((typeCache != null) && (typeCache instanceof Double)) {
2405             double val = ((Double)typeCache).doubleValue();
2406             useTypeCache();
2407             return val;
2408         }
2409         setRadix(10);
2410         clearCaches();
2411         // Search for next float
2412         try {
2413             return Double.parseDouble(processFloatToken(next(floatPattern())));
2414         } catch (NumberFormatException nfe) {
2415             position = matcher.start(); // don't skip bad token
2416             throw new InputMismatchException(nfe.getMessage());
2417         }
2418     }
2419 
2420     // Convenience methods for scanning multi precision numbers
2421 
2422     /**
2423      * Returns true if the next token in this scanner's input can be
2424      * interpreted as a <code>BigInteger</code> in the default radix using the
2425      * {@link #nextBigInteger} method. The scanner does not advance past any
2426      * input.
2427      *
2428      * @return true if and only if this scanner's next token is a valid
2429      *         <code>BigInteger</code>
2430      * @throws IllegalStateException if this scanner is closed
2431      */
2432     public boolean hasNextBigInteger() {
2433         return hasNextBigInteger(defaultRadix);
2434     }
2435 
2436     /**
2437      * Returns true if the next token in this scanner's input can be
2438      * interpreted as a <code>BigInteger</code> in the specified radix using
2439      * the {@link #nextBigInteger} method. The scanner does not advance past
2440      * any input.
2441      *
2442      * @param radix the radix used to interpret the token as an integer
2443      * @return true if and only if this scanner's next token is a valid
2444      *         <code>BigInteger</code>
2445      * @throws IllegalStateException if this scanner is closed
2446      */
2447     public boolean hasNextBigInteger(int radix) {
2448         setRadix(radix);
2449         boolean result = hasNext(integerPattern());
2450         if (result) { // Cache it
2451             try {
2452                 String s = (matcher.group(SIMPLE_GROUP_INDEX) == null) ?
2453                     processIntegerToken(hasNextResult) :
2454                     hasNextResult;
2455                 typeCache = new BigInteger(s, radix);
2456             } catch (NumberFormatException nfe) {
2457                 result = false;
2458             }
2459         }
2460         return result;
2461     }
2462 
2463     /**
2464      * Scans the next token of the input as a {@link java.math.BigInteger
2465      * BigInteger}.
2466      *
2467      * <p> An invocation of this method of the form
2468      * <tt>nextBigInteger()</tt> behaves in exactly the same way as the
2469      * invocation <tt>nextBigInteger(radix)</tt>, where <code>radix</code>
2470      * is the default radix of this scanner.
2471      *
2472      * @return the <tt>BigInteger</tt> scanned from the input
2473      * @throws InputMismatchException
2474      *         if the next token does not match the <i>Integer</i>
2475      *         regular expression, or is out of range
2476      * @throws NoSuchElementException if the input is exhausted
2477      * @throws IllegalStateException if this scanner is closed
2478      */
2479     public BigInteger nextBigInteger() {
2480         return nextBigInteger(defaultRadix);
2481     }
2482 
2483     /**
2484      * Scans the next token of the input as a {@link java.math.BigInteger
2485      * BigInteger}.
2486      *
2487      * <p> If the next token matches the <a
2488      * href="#Integer-regex"><i>Integer</i></a> regular expression defined
2489      * above then the token is converted into a <tt>BigInteger</tt> value as if
2490      * by removing all group separators, mapping non-ASCII digits into ASCII
2491      * digits via the {@link Character#digit Character.digit}, and passing the
2492      * resulting string to the {@link
2493      * java.math.BigInteger#BigInteger(java.lang.String)
2494      * BigInteger(String, int)} constructor with the specified radix.
2495      *
2496      * @param radix the radix used to interpret the token
2497      * @return the <tt>BigInteger</tt> scanned from the input
2498      * @throws InputMismatchException
2499      *         if the next token does not match the <i>Integer</i>
2500      *         regular expression, or is out of range
2501      * @throws NoSuchElementException if the input is exhausted
2502      * @throws IllegalStateException if this scanner is closed
2503      */
2504     public BigInteger nextBigInteger(int radix) {
2505         // Check cached result
2506         if ((typeCache != null) && (typeCache instanceof BigInteger)
2507             && this.radix == radix) {
2508             BigInteger val = (BigInteger)typeCache;
2509             useTypeCache();
2510             return val;
2511         }
2512         setRadix(radix);
2513         clearCaches();
2514         // Search for next int
2515         try {
2516             String s = next(integerPattern());
2517             if (matcher.group(SIMPLE_GROUP_INDEX) == null)
2518                 s = processIntegerToken(s);
2519             return new BigInteger(s, radix);
2520         } catch (NumberFormatException nfe) {
2521             position = matcher.start(); // don't skip bad token
2522             throw new InputMismatchException(nfe.getMessage());
2523         }
2524     }
2525 
2526     /**
2527      * Returns true if the next token in this scanner's input can be
2528      * interpreted as a <code>BigDecimal</code> using the
2529      * {@link #nextBigDecimal} method. The scanner does not advance past any
2530      * input.
2531      *
2532      * @return true if and only if this scanner's next token is a valid
2533      *         <code>BigDecimal</code>
2534      * @throws IllegalStateException if this scanner is closed
2535      */
2536     public boolean hasNextBigDecimal() {
2537         setRadix(10);
2538         boolean result = hasNext(decimalPattern());
2539         if (result) { // Cache it
2540             try {
2541                 String s = processFloatToken(hasNextResult);
2542                 typeCache = new BigDecimal(s);
2543             } catch (NumberFormatException nfe) {
2544                 result = false;
2545             }
2546         }
2547         return result;
2548     }
2549 
2550     /**
2551      * Scans the next token of the input as a {@link java.math.BigDecimal
2552      * BigDecimal}.
2553      *
2554      * <p> If the next token matches the <a
2555      * href="#Decimal-regex"><i>Decimal</i></a> regular expression defined
2556      * above then the token is converted into a <tt>BigDecimal</tt> value as if
2557      * by removing all group separators, mapping non-ASCII digits into ASCII
2558      * digits via the {@link Character#digit Character.digit}, and passing the
2559      * resulting string to the {@link
2560      * java.math.BigDecimal#BigDecimal(java.lang.String) BigDecimal(String)}
2561      * constructor.
2562      *
2563      * @return the <tt>BigDecimal</tt> scanned from the input
2564      * @throws InputMismatchException
2565      *         if the next token does not match the <i>Decimal</i>
2566      *         regular expression, or is out of range
2567      * @throws NoSuchElementException if the input is exhausted
2568      * @throws IllegalStateException if this scanner is closed
2569      */
2570     public BigDecimal nextBigDecimal() {
2571         // Check cached result
2572         if ((typeCache != null) && (typeCache instanceof BigDecimal)) {
2573             BigDecimal val = (BigDecimal)typeCache;
2574             useTypeCache();
2575             return val;
2576         }
2577         setRadix(10);
2578         clearCaches();
2579         // Search for next float
2580         try {
2581             String s = processFloatToken(next(decimalPattern()));
2582             return new BigDecimal(s);
2583         } catch (NumberFormatException nfe) {
2584             position = matcher.start(); // don't skip bad token
2585             throw new InputMismatchException(nfe.getMessage());
2586         }
2587     }
2588 
2589     /**
2590      * Resets this scanner.
2591      *
2592      * <p> Resetting a scanner discards all of its explicit state
2593      * information which may have been changed by invocations of {@link
2594      * #useDelimiter}, {@link #useLocale}, or {@link #useRadix}.
2595      *
2596      * <p> An invocation of this method of the form
2597      * <tt>scanner.reset()</tt> behaves in exactly the same way as the
2598      * invocation
2599      *
2600      * <blockquote><pre>{@code
2601      *   scanner.useDelimiter("\\p{javaWhitespace}+")
2602      *          .useLocale(Locale.getDefault(Locale.Category.FORMAT))
2603      *          .useRadix(10);
2604      * }</pre></blockquote>
2605      *
2606      * @return this scanner
2607      *
2608      * @since 1.6
2609      */
2610     public Scanner reset() {
2611         delimPattern = WHITESPACE_PATTERN;
2612         useLocale(Locale.getDefault(Locale.Category.FORMAT));
2613         useRadix(10);
2614         clearCaches();
2615         return this;
2616     }
2617 }


  25 
  26 package java.util;
  27 
  28 import java.nio.file.Path;
  29 import java.nio.file.Files;
  30 import java.util.regex.*;
  31 import java.io.*;
  32 import java.math.*;
  33 import java.nio.*;
  34 import java.nio.channels.*;
  35 import java.nio.charset.*;
  36 import java.text.*;
  37 import java.util.Locale;
  38 
  39 import sun.misc.LRUCache;
  40 
  41 /**
  42  * A simple text scanner which can parse primitive types and strings using
  43  * regular expressions.
  44  *
  45  * <p>A {@code Scanner} breaks its input into tokens using a
  46  * delimiter pattern, which by default matches whitespace. The resulting
  47  * tokens may then be converted into values of different types using the
  48  * various {@code next} methods.
  49  *
  50  * <p>For example, this code allows a user to read a number from
  51  * {@code System.in}:
  52  * <blockquote><pre>{@code
  53  *     Scanner sc = new Scanner(System.in);
  54  *     int i = sc.nextInt();
  55  * }</pre></blockquote>
  56  *
  57  * <p>As another example, this code allows {@code long} types to be
  58  * assigned from entries in a file {@code myNumbers}:
  59  * <blockquote><pre>{@code
  60  *      Scanner sc = new Scanner(new File("myNumbers"));
  61  *      while (sc.hasNextLong()) {
  62  *          long aLong = sc.nextLong();
  63  *      }
  64  * }</pre></blockquote>
  65  *
  66  * <p>The scanner can also use delimiters other than whitespace. This
  67  * example reads several items in from a string:
  68  * <blockquote><pre>{@code
  69  *     String input = "1 fish 2 fish red fish blue fish";
  70  *     Scanner s = new Scanner(input).useDelimiter("\\s*fish\\s*");
  71  *     System.out.println(s.nextInt());
  72  *     System.out.println(s.nextInt());
  73  *     System.out.println(s.next());
  74  *     System.out.println(s.next());
  75  *     s.close();
  76  * }</pre></blockquote>
  77  * <p>
  78  * prints the following output:


  89  *     String input = "1 fish 2 fish red fish blue fish";
  90  *     Scanner s = new Scanner(input);
  91  *     s.findInLine("(\\d+) fish (\\d+) fish (\\w+) fish (\\w+)");
  92  *     MatchResult result = s.match();
  93  *     for (int i=1; i<=result.groupCount(); i++)
  94  *         System.out.println(result.group(i));
  95  *     s.close();
  96  * }</pre></blockquote>
  97  *
  98  * <p>The <a name="default-delimiter">default whitespace delimiter</a> used
  99  * by a scanner is as recognized by {@link java.lang.Character}.{@link
 100  * java.lang.Character#isWhitespace(char) isWhitespace}. The {@link #reset}
 101  * method will reset the value of the scanner's delimiter to the default
 102  * whitespace delimiter regardless of whether it was previously changed.
 103  *
 104  * <p>A scanning operation may block waiting for input.
 105  *
 106  * <p>The {@link #next} and {@link #hasNext} methods and their
 107  * primitive-type companion methods (such as {@link #nextInt} and
 108  * {@link #hasNextInt}) first skip any input that matches the delimiter
 109  * pattern, and then attempt to return the next token. Both {@code hasNext}
 110  * and {@code next} methods may block waiting for further input.  Whether a
 111  * {@code hasNext} method blocks has no connection to whether or not its
 112  * associated {@code next} method will block.
 113  *
 114  * <p> The {@link #findInLine}, {@link #findWithinHorizon}, and {@link #skip}
 115  * methods operate independently of the delimiter pattern. These methods will
 116  * attempt to match the specified pattern with no regard to delimiters in the
 117  * input and thus can be used in special circumstances where delimiters are
 118  * not relevant. These methods may block waiting for more input.
 119  *
 120  * <p>When a scanner throws an {@link InputMismatchException}, the scanner
 121  * will not pass the token that caused the exception, so that it may be
 122  * retrieved or skipped via some other method.
 123  *
 124  * <p>Depending upon the type of delimiting pattern, empty tokens may be
 125  * returned. For example, the pattern {@code "\\s+"} will return no empty
 126  * tokens since it matches multiple instances of the delimiter. The delimiting
 127  * pattern {@code "\\s"} could return empty tokens since it only passes one
 128  * space at a time.
 129  *
 130  * <p> A scanner can read text from any object which implements the {@link
 131  * java.lang.Readable} interface.  If an invocation of the underlying
 132  * readable's {@link java.lang.Readable#read} method throws an {@link
 133  * java.io.IOException} then the scanner assumes that the end of the input
 134  * has been reached.  The most recent {@code IOException} thrown by the
 135  * underlying readable can be retrieved via the {@link #ioException} method.
 136  *
 137  * <p>When a {@code Scanner} is closed, it will close its input source
 138  * if the source implements the {@link java.io.Closeable} interface.
 139  *
 140  * <p>A {@code Scanner} is not safe for multithreaded use without
 141  * external synchronization.
 142  *
 143  * <p>Unless otherwise mentioned, passing a {@code null} parameter into
 144  * any method of a {@code Scanner} will cause a
 145  * {@code NullPointerException} to be thrown.
 146  *
 147  * <p>A scanner will default to interpreting numbers as decimal unless a
 148  * different radix has been set by using the {@link #useRadix} method. The
 149  * {@link #reset} method will reset the value of the scanner's radix to
 150  * {@code 10} regardless of whether it was previously changed.
 151  *
 152  * <h3> <a name="localized-numbers">Localized numbers</a> </h3>
 153  *
 154  * <p> An instance of this class is capable of scanning numbers in the standard
 155  * formats as well as in the formats of the scanner's locale. A scanner's
 156  * <a name="initial-locale">initial locale </a>is the value returned by the {@link
 157  * java.util.Locale#getDefault(Locale.Category)
 158  * Locale.getDefault(Locale.Category.FORMAT)} method; it may be changed via the {@link
 159  * #useLocale} method. The {@link #reset} method will reset the value of the
 160  * scanner's locale to the initial locale regardless of whether it was
 161  * previously changed.
 162  *
 163  * <p>The localized formats are defined in terms of the following parameters,
 164  * which for a particular locale are taken from that locale's {@link
 165  * java.text.DecimalFormat DecimalFormat} object, {@code df}, and its and
 166  * {@link java.text.DecimalFormatSymbols DecimalFormatSymbols} object,
 167  * {@code dfs}.
 168  *
 169  * <blockquote><dl>
 170  *     <dt><i>LocalGroupSeparator&nbsp;&nbsp;</i>
 171  *         <dd>The character used to separate thousands groups,
 172  *         <i>i.e.,</i>&nbsp;{@code dfs.}{@link
 173  *         java.text.DecimalFormatSymbols#getGroupingSeparator
 174  *         getGroupingSeparator()}
 175  *     <dt><i>LocalDecimalSeparator&nbsp;&nbsp;</i>
 176  *         <dd>The character used for the decimal point,
 177  *     <i>i.e.,</i>&nbsp;{@code dfs.}{@link
 178  *     java.text.DecimalFormatSymbols#getDecimalSeparator
 179  *     getDecimalSeparator()}
 180  *     <dt><i>LocalPositivePrefix&nbsp;&nbsp;</i>
 181  *         <dd>The string that appears before a positive number (may
 182  *         be empty), <i>i.e.,</i>&nbsp;{@code df.}{@link
 183  *         java.text.DecimalFormat#getPositivePrefix
 184  *         getPositivePrefix()}
 185  *     <dt><i>LocalPositiveSuffix&nbsp;&nbsp;</i>
 186  *         <dd>The string that appears after a positive number (may be
 187  *         empty), <i>i.e.,</i>&nbsp;{@code df.}{@link
 188  *         java.text.DecimalFormat#getPositiveSuffix
 189  *         getPositiveSuffix()}
 190  *     <dt><i>LocalNegativePrefix&nbsp;&nbsp;</i>
 191  *         <dd>The string that appears before a negative number (may
 192  *         be empty), <i>i.e.,</i>&nbsp;{@code df.}{@link
 193  *         java.text.DecimalFormat#getNegativePrefix
 194  *         getNegativePrefix()}
 195  *     <dt><i>LocalNegativeSuffix&nbsp;&nbsp;</i>
 196  *         <dd>The string that appears after a negative number (may be
 197  *         empty), <i>i.e.,</i>&nbsp;{@code df.}{@link
 198  *     java.text.DecimalFormat#getNegativeSuffix
 199  *     getNegativeSuffix()}
 200  *     <dt><i>LocalNaN&nbsp;&nbsp;</i>
 201  *         <dd>The string that represents not-a-number for
 202  *         floating-point values,
 203  *         <i>i.e.,</i>&nbsp;{@code dfs.}{@link
 204  *         java.text.DecimalFormatSymbols#getNaN
 205  *         getNaN()}
 206  *     <dt><i>LocalInfinity&nbsp;&nbsp;</i>
 207  *         <dd>The string that represents infinity for floating-point
 208  *         values, <i>i.e.,</i>&nbsp;{@code dfs.}{@link
 209  *         java.text.DecimalFormatSymbols#getInfinity
 210  *         getInfinity()}
 211  * </dl></blockquote>
 212  *
 213  * <h4> <a name="number-syntax">Number syntax</a> </h4>
 214  *
 215  * <p> The strings that can be parsed as numbers by an instance of this class
 216  * are specified in terms of the following regular-expression grammar, where
 217  * Rmax is the highest digit in the radix being used (for example, Rmax is 9 in base 10).
 218  *
 219  * <dl>
 220  *   <dt><i>NonAsciiDigit</i>:
 221  *       <dd>A non-ASCII character c for which
 222  *            {@link java.lang.Character#isDigit Character.isDigit}{@code (c)}
 223  *                        returns&nbsp;true
 224  *
 225  *   <dt><i>Non0Digit</i>:
 226  *       <dd>{@code [1-}<i>Rmax</i>{@code ] | }<i>NonASCIIDigit</i>
 227  *
 228  *   <dt><i>Digit</i>:
 229  *       <dd>{@code [0-}<i>Rmax</i>{@code ] | }<i>NonASCIIDigit</i>
 230  *
 231  *   <dt><i>GroupedNumeral</i>:
 232  *       <dd><code>(&nbsp;</code><i>Non0Digit</i>
 233  *                   <i>Digit</i>{@code ?
 234  *                   }<i>Digit</i>{@code ?}
 235  *       <dd>&nbsp;&nbsp;&nbsp;&nbsp;<code>(&nbsp;</code><i>LocalGroupSeparator</i>
 236  *                         <i>Digit</i>
 237  *                         <i>Digit</i>
 238  *                         <i>Digit</i>{@code  )+ )}
 239  *
 240  *   <dt><i>Numeral</i>:
 241  *       <dd>{@code ( ( }<i>Digit</i>{@code + )
 242  *               | }<i>GroupedNumeral</i>{@code  )}
 243  *
 244  *   <dt><a name="Integer-regex"><i>Integer</i>:</a>
 245  *       <dd>{@code ( [-+]? ( }<i>Numeral</i>{@code 
 246  *                               ) )}
 247  *       <dd>{@code | }<i>LocalPositivePrefix</i> <i>Numeral</i>
 248  *                      <i>LocalPositiveSuffix</i>
 249  *       <dd>{@code | }<i>LocalNegativePrefix</i> <i>Numeral</i>
 250  *                 <i>LocalNegativeSuffix</i>
 251  *
 252  *   <dt><i>DecimalNumeral</i>:
 253  *       <dd><i>Numeral</i>
 254  *       <dd>{@code | }<i>Numeral</i>
 255  *                 <i>LocalDecimalSeparator</i>
 256  *                 <i>Digit</i>{@code *}
 257  *       <dd>{@code | }<i>LocalDecimalSeparator</i>
 258  *                 <i>Digit</i>{@code +}
 259  *
 260  *   <dt><i>Exponent</i>:
 261  *       <dd>{@code ( [eE] [+-]? }<i>Digit</i>{@code + )}
 262  *
 263  *   <dt><a name="Decimal-regex"><i>Decimal</i>:</a>
 264  *       <dd>{@code ( [-+]? }<i>DecimalNumeral</i>
 265  *                         <i>Exponent</i>{@code ? )}
 266  *       <dd>{@code | }<i>LocalPositivePrefix</i>
 267  *                 <i>DecimalNumeral</i>
 268  *                 <i>LocalPositiveSuffix</i>
 269  *                 <i>Exponent</i>{@code ?}
 270  *       <dd>{@code | }<i>LocalNegativePrefix</i>
 271  *                 <i>DecimalNumeral</i>
 272  *                 <i>LocalNegativeSuffix</i>
 273  *                 <i>Exponent</i>{@code ?}
 274  *
 275  *   <dt><i>HexFloat</i>:
 276  *       <dd>{@code [-+]? 0[xX][0-9a-fA-F]*\.[0-9a-fA-F]+
 277  *                 ([pP][-+]?[0-9]+)?}
 278  *
 279  *   <dt><i>NonNumber</i>:
 280  *       <dd>{@code NaN
 281  *                          | }<i>LocalNan</i>{@code 
 282  *                          | Infinity
 283  *                          | }<i>LocalInfinity</i>
 284  *
 285  *   <dt><i>SignedNonNumber</i>:
 286  *       <dd>{@code ( [-+]? }<i>NonNumber</i>{@code  )}
 287  *       <dd>{@code | }<i>LocalPositivePrefix</i>
 288  *                 <i>NonNumber</i>
 289  *                 <i>LocalPositiveSuffix</i>
 290  *       <dd>{@code | }<i>LocalNegativePrefix</i>
 291  *                 <i>NonNumber</i>
 292  *                 <i>LocalNegativeSuffix</i>
 293  *
 294  *   <dt><a name="Float-regex"><i>Float</i></a>:
 295  *       <dd><i>Decimal</i>
 296  *           {@code | }<i>HexFloat</i>
 297  *           {@code | }<i>SignedNonNumber</i>
 298  *
 299  * </dl>
 300  * <p>Whitespace is not significant in the above regular expressions.
 301  *
 302  * @since   1.5
 303  */
 304 public final class Scanner implements Iterator<String>, Closeable {
 305 
 306     // Internal buffer used to hold input
 307     private CharBuffer buf;
 308 
 309     // Size of internal character buffer
 310     private static final int BUFFER_SIZE = 1024; // change to 1024;
 311 
 312     // The index into the buffer currently held by the Scanner
 313     private int position;
 314 
 315     // Internal matcher used for finding delimiters
 316     private Matcher matcher;
 317 


 504         floatPattern = Pattern.compile(decimal + "|" + hexFloat + "|" +
 505                                        signedNonNumber);
 506         decimalPattern = Pattern.compile(decimal);
 507     }
 508     private Pattern floatPattern() {
 509         if (floatPattern == null) {
 510             buildFloatAndDecimalPattern();
 511         }
 512         return floatPattern;
 513     }
 514     private Pattern decimalPattern() {
 515         if (decimalPattern == null) {
 516             buildFloatAndDecimalPattern();
 517         }
 518         return decimalPattern;
 519     }
 520 
 521     // Constructors
 522 
 523     /**
 524      * Constructs a {@code Scanner} that returns values scanned
 525      * from the specified source delimited by the specified pattern.
 526      *
 527      * @param source A character source implementing the Readable interface
 528      * @param pattern A delimiting pattern
 529      */
 530     private Scanner(Readable source, Pattern pattern) {
 531         assert source != null : "source should not be null";
 532         assert pattern != null : "pattern should not be null";
 533         this.source = source;
 534         delimPattern = pattern;
 535         buf = CharBuffer.allocate(BUFFER_SIZE);
 536         buf.limit(0);
 537         matcher = delimPattern.matcher(buf);
 538         matcher.useTransparentBounds(true);
 539         matcher.useAnchoringBounds(false);
 540         useLocale(Locale.getDefault(Locale.Category.FORMAT));
 541     }
 542 
 543     /**
 544      * Constructs a new {@code Scanner} that produces values scanned
 545      * from the specified source.
 546      *
 547      * @param  source A character source implementing the {@link Readable}
 548      *         interface
 549      */
 550     public Scanner(Readable source) {
 551         this(Objects.requireNonNull(source, "source"), WHITESPACE_PATTERN);
 552     }
 553 
 554     /**
 555      * Constructs a new {@code Scanner} that produces values scanned
 556      * from the specified input stream. Bytes from the stream are converted
 557      * into characters using the underlying platform's
 558      * {@linkplain java.nio.charset.Charset#defaultCharset() default charset}.
 559      *
 560      * @param  source An input stream to be scanned
 561      */
 562     public Scanner(InputStream source) {
 563         this(new InputStreamReader(source), WHITESPACE_PATTERN);
 564     }
 565 
 566     /**
 567      * Constructs a new {@code Scanner} that produces values scanned
 568      * from the specified input stream. Bytes from the stream are converted
 569      * into characters using the specified charset.
 570      *
 571      * @param  source An input stream to be scanned
 572      * @param charsetName The encoding type used to convert bytes from the
 573      *        stream into characters to be scanned
 574      * @throws IllegalArgumentException if the specified character set
 575      *         does not exist
 576      */
 577     public Scanner(InputStream source, String charsetName) {
 578         this(makeReadable(Objects.requireNonNull(source, "source"), toCharset(charsetName)),
 579              WHITESPACE_PATTERN);
 580     }
 581 
 582     /**
 583      * Returns a charset object for the given charset name.
 584      * @throws NullPointerException          is csn is null
 585      * @throws IllegalArgumentException      if the charset is not supported
 586      */
 587     private static Charset toCharset(String csn) {
 588         Objects.requireNonNull(csn, "charsetName");
 589         try {
 590             return Charset.forName(csn);
 591         } catch (IllegalCharsetNameException|UnsupportedCharsetException e) {
 592             // IllegalArgumentException should be thrown
 593             throw new IllegalArgumentException(e);
 594         }
 595     }
 596 
 597     private static Readable makeReadable(InputStream source, Charset charset) {
 598         return new InputStreamReader(source, charset);
 599     }
 600 
 601     /**
 602      * Constructs a new {@code Scanner} that produces values scanned
 603      * from the specified file. Bytes from the file are converted into
 604      * characters using the underlying platform's
 605      * {@linkplain java.nio.charset.Charset#defaultCharset() default charset}.
 606      *
 607      * @param  source A file to be scanned
 608      * @throws FileNotFoundException if source is not found
 609      */
 610     public Scanner(File source) throws FileNotFoundException {
 611         this((ReadableByteChannel)(new FileInputStream(source).getChannel()));
 612     }
 613 
 614     /**
 615      * Constructs a new {@code Scanner} that produces values scanned
 616      * from the specified file. Bytes from the file are converted into
 617      * characters using the specified charset.
 618      *
 619      * @param  source A file to be scanned
 620      * @param charsetName The encoding type used to convert bytes from the file
 621      *        into characters to be scanned
 622      * @throws FileNotFoundException if source is not found
 623      * @throws IllegalArgumentException if the specified encoding is
 624      *         not found
 625      */
 626     public Scanner(File source, String charsetName)
 627         throws FileNotFoundException
 628     {
 629         this(Objects.requireNonNull(source), toDecoder(charsetName));
 630     }
 631 
 632     private Scanner(File source, CharsetDecoder dec)
 633         throws FileNotFoundException
 634     {
 635         this(makeReadable((ReadableByteChannel)(new FileInputStream(source).getChannel()), dec));
 636     }
 637 
 638     private static CharsetDecoder toDecoder(String charsetName) {
 639         Objects.requireNonNull(charsetName, "charsetName");
 640         try {
 641             return Charset.forName(charsetName).newDecoder();
 642         } catch (IllegalCharsetNameException|UnsupportedCharsetException unused) {
 643             throw new IllegalArgumentException(charsetName);
 644         }
 645     }
 646 
 647     private static Readable makeReadable(ReadableByteChannel source,
 648                                          CharsetDecoder dec) {
 649         return Channels.newReader(source, dec, -1);
 650     }
 651 
 652     /**
 653      * Constructs a new {@code Scanner} that produces values scanned
 654      * from the specified file. Bytes from the file are converted into
 655      * characters using the underlying platform's
 656      * {@linkplain java.nio.charset.Charset#defaultCharset() default charset}.
 657      *
 658      * @param   source
 659      *          the path to the file to be scanned
 660      * @throws  IOException
 661      *          if an I/O error occurs opening source
 662      *
 663      * @since   1.7
 664      */
 665     public Scanner(Path source)
 666         throws IOException
 667     {
 668         this(Files.newInputStream(source));
 669     }
 670 
 671     /**
 672      * Constructs a new {@code Scanner} that produces values scanned
 673      * from the specified file. Bytes from the file are converted into
 674      * characters using the specified charset.
 675      *
 676      * @param   source
 677      *          the path to the file to be scanned
 678      * @param   charsetName
 679      *          The encoding type used to convert bytes from the file
 680      *          into characters to be scanned
 681      * @throws  IOException
 682      *          if an I/O error occurs opening source
 683      * @throws  IllegalArgumentException
 684      *          if the specified encoding is not found
 685      * @since   1.7
 686      */
 687     public Scanner(Path source, String charsetName) throws IOException {
 688         this(Objects.requireNonNull(source), toCharset(charsetName));
 689     }
 690 
 691     private Scanner(Path source, Charset charset)  throws IOException {
 692         this(makeReadable(Files.newInputStream(source), charset));
 693     }
 694 
 695     /**
 696      * Constructs a new {@code Scanner} that produces values scanned
 697      * from the specified string.
 698      *
 699      * @param  source A string to scan
 700      */
 701     public Scanner(String source) {
 702         this(new StringReader(source), WHITESPACE_PATTERN);
 703     }
 704 
 705     /**
 706      * Constructs a new {@code Scanner} that produces values scanned
 707      * from the specified channel. Bytes from the source are converted into
 708      * characters using the underlying platform's
 709      * {@linkplain java.nio.charset.Charset#defaultCharset() default charset}.
 710      *
 711      * @param  source A channel to scan
 712      */
 713     public Scanner(ReadableByteChannel source) {
 714         this(makeReadable(Objects.requireNonNull(source, "source")),
 715              WHITESPACE_PATTERN);
 716     }
 717 
 718     private static Readable makeReadable(ReadableByteChannel source) {
 719         return makeReadable(source, Charset.defaultCharset().newDecoder());
 720     }
 721 
 722     /**
 723      * Constructs a new {@code Scanner} that produces values scanned
 724      * from the specified channel. Bytes from the source are converted into
 725      * characters using the specified charset.
 726      *
 727      * @param  source A channel to scan
 728      * @param charsetName The encoding type used to convert bytes from the
 729      *        channel into characters to be scanned
 730      * @throws IllegalArgumentException if the specified character set
 731      *         does not exist
 732      */
 733     public Scanner(ReadableByteChannel source, String charsetName) {
 734         this(makeReadable(Objects.requireNonNull(source, "source"), toDecoder(charsetName)),
 735              WHITESPACE_PATTERN);
 736     }
 737 
 738     // Private primitives used to support scanning
 739 
 740     private void saveState() {
 741         savedScannerPosition = position;
 742     }
 743 


1060             return null;
1061 
1062         // Read more to find pattern
1063         needInput = true;
1064         return null;
1065     }
1066 
1067     // Throws if the scanner is closed
1068     private void ensureOpen() {
1069         if (closed)
1070             throw new IllegalStateException("Scanner closed");
1071     }
1072 
1073     // Public methods
1074 
1075     /**
1076      * Closes this scanner.
1077      *
1078      * <p> If this scanner has not yet been closed then if its underlying
1079      * {@linkplain java.lang.Readable readable} also implements the {@link
1080      * java.io.Closeable} interface then the readable's {@code close} method
1081      * will be invoked.  If this scanner is already closed then invoking this
1082      * method will have no effect.
1083      *
1084      * <p>Attempting to perform search operations after a scanner has
1085      * been closed will result in an {@link IllegalStateException}.
1086      *
1087      */
1088     public void close() {
1089         if (closed)
1090             return;
1091         if (source instanceof Closeable) {
1092             try {
1093                 ((Closeable)source).close();
1094             } catch (IOException ioe) {
1095                 lastException = ioe;
1096             }
1097         }
1098         sourceClosed = true;
1099         source = null;
1100         closed = true;
1101     }
1102 
1103     /**
1104      * Returns the {@code IOException} last thrown by this
1105      * {@code Scanner}'s underlying {@code Readable}. This method
1106      * returns {@code null} if no such exception exists.
1107      *
1108      * @return the last exception thrown by this scanner's readable
1109      */
1110     public IOException ioException() {
1111         return lastException;
1112     }
1113 
1114     /**
1115      * Returns the {@code Pattern} this {@code Scanner} is currently
1116      * using to match delimiters.
1117      *
1118      * @return this scanner's delimiting pattern.
1119      */
1120     public Pattern delimiter() {
1121         return delimPattern;
1122     }
1123 
1124     /**
1125      * Sets this scanner's delimiting pattern to the specified pattern.
1126      *
1127      * @param pattern A delimiting pattern
1128      * @return this scanner
1129      */
1130     public Scanner useDelimiter(Pattern pattern) {
1131         delimPattern = pattern;
1132         return this;
1133     }
1134 
1135     /**
1136      * Sets this scanner's delimiting pattern to a pattern constructed from
1137      * the specified {@code String}.
1138      *
1139      * <p> An invocation of this method of the form
1140      * {@code useDelimiter(pattern)} behaves in exactly the same way as the
1141      * invocation {@code useDelimiter(Pattern.compile(pattern))}.
1142      *
1143      * <p> Invoking the {@link #reset} method will set the scanner's delimiter
1144      * to the <a href= "#default-delimiter">default</a>.
1145      *
1146      * @param pattern A string specifying a delimiting pattern
1147      * @return this scanner
1148      */
1149     public Scanner useDelimiter(String pattern) {
1150         delimPattern = patternCache.forName(pattern);
1151         return this;
1152     }
1153 
1154     /**
1155      * Returns this scanner's locale.
1156      *
1157      * <p>A scanner's locale affects many elements of its default
1158      * primitive matching regular expressions; see
1159      * <a href= "#localized-numbers">localized numbers</a> above.
1160      *
1161      * @return this scanner's locale


1219     /**
1220      * Returns this scanner's default radix.
1221      *
1222      * <p>A scanner's radix affects elements of its default
1223      * number matching regular expressions; see
1224      * <a href= "#localized-numbers">localized numbers</a> above.
1225      *
1226      * @return the default radix of this scanner
1227      */
1228     public int radix() {
1229         return this.defaultRadix;
1230     }
1231 
1232     /**
1233      * Sets this scanner's default radix to the specified radix.
1234      *
1235      * <p>A scanner's radix affects elements of its default
1236      * number matching regular expressions; see
1237      * <a href= "#localized-numbers">localized numbers</a> above.
1238      *
1239      * <p>If the radix is less than {@code Character.MIN_RADIX}
1240      * or greater than {@code Character.MAX_RADIX}, then an
1241      * {@code IllegalArgumentException} is thrown.
1242      *
1243      * <p>Invoking the {@link #reset} method will set the scanner's radix to
1244      * {@code 10}.
1245      *
1246      * @param radix The radix to use when scanning numbers
1247      * @return this scanner
1248      * @throws IllegalArgumentException if radix is out of range
1249      */
1250     public Scanner useRadix(int radix) {
1251         if ((radix < Character.MIN_RADIX) || (radix > Character.MAX_RADIX))
1252             throw new IllegalArgumentException("radix:"+radix);
1253 
1254         if (this.defaultRadix == radix)
1255             return this;
1256         this.defaultRadix = radix;
1257         // Force rebuilding and recompilation of radix dependent patterns
1258         integerPattern = null;
1259         return this;
1260     }
1261 
1262     // The next operation should occur in the specified radix but
1263     // the default is left untouched.
1264     private void setRadix(int radix) {
1265         if (this.radix != radix) {
1266             // Force rebuilding and recompilation of radix dependent patterns
1267             integerPattern = null;
1268             this.radix = radix;
1269         }
1270     }
1271 
1272     /**
1273      * Returns the match result of the last scanning operation performed
1274      * by this scanner. This method throws {@code IllegalStateException}
1275      * if no match has been performed, or if the last match was
1276      * not successful.
1277      *
1278      * <p>The various {@code next}methods of {@code Scanner}
1279      * make a match result available if they complete without throwing an
1280      * exception. For instance, after an invocation of the {@link #nextInt}
1281      * method that returned an int, this method returns a
1282      * {@code MatchResult} for the search of the
1283      * <a href="#Integer-regex"><i>Integer</i></a> regular expression
1284      * defined above. Similarly the {@link #findInLine},
1285      * {@link #findWithinHorizon}, and {@link #skip} methods will make a
1286      * match available if they succeed.
1287      *
1288      * @return a match result for the last match operation
1289      * @throws IllegalStateException  If no match result is available
1290      */
1291     public MatchResult match() {
1292         if (!matchValid)
1293             throw new IllegalStateException("No match result available");
1294         return matcher.toMatchResult();
1295     }
1296 
1297     /**
1298      * <p>Returns the string representation of this {@code Scanner}. The
1299      * string representation of a {@code Scanner} contains information
1300      * that may be useful for debugging. The exact format is unspecified.
1301      *
1302      * @return  The string representation of this scanner
1303      */
1304     public String toString() {
1305         StringBuilder sb = new StringBuilder();
1306         sb.append("java.util.Scanner");
1307         sb.append("[delimiters=" + delimPattern + "]");
1308         sb.append("[position=" + position + "]");
1309         sb.append("[match valid=" + matchValid + "]");
1310         sb.append("[need input=" + needInput + "]");
1311         sb.append("[source closed=" + sourceClosed + "]");
1312         sb.append("[skipped=" + skipped + "]");
1313         sb.append("[group separator=" + groupSeparator + "]");
1314         sb.append("[decimal separator=" + decimalSeparator + "]");
1315         sb.append("[positive prefix=" + positivePrefix + "]");
1316         sb.append("[negative prefix=" + negativePrefix + "]");
1317         sb.append("[positive suffix=" + positiveSuffix + "]");
1318         sb.append("[negative suffix=" + negativeSuffix + "]");
1319         sb.append("[NaN string=" + nanString + "]");


1330      * @throws IllegalStateException if this scanner is closed
1331      * @see java.util.Iterator
1332      */
1333     public boolean hasNext() {
1334         ensureOpen();
1335         saveState();
1336         while (!sourceClosed) {
1337             if (hasTokenInBuffer())
1338                 return revertState(true);
1339             readInput();
1340         }
1341         boolean result = hasTokenInBuffer();
1342         return revertState(result);
1343     }
1344 
1345     /**
1346      * Finds and returns the next complete token from this scanner.
1347      * A complete token is preceded and followed by input that matches
1348      * the delimiter pattern. This method may block while waiting for input
1349      * to scan, even if a previous invocation of {@link #hasNext} returned
1350      * {@code true}.
1351      *
1352      * @return the next token
1353      * @throws NoSuchElementException if no more tokens are available
1354      * @throws IllegalStateException if this scanner is closed
1355      * @see java.util.Iterator
1356      */
1357     public String next() {
1358         ensureOpen();
1359         clearCaches();
1360 
1361         while (true) {
1362             String token = getCompleteTokenInBuffer(null);
1363             if (token != null) {
1364                 matchValid = true;
1365                 skipped = false;
1366                 return token;
1367             }
1368             if (needInput)
1369                 readInput();
1370             else
1371                 throwFor();
1372         }
1373     }
1374 
1375     /**
1376      * The remove operation is not supported by this implementation of
1377      * {@code Iterator}.
1378      *
1379      * @throws UnsupportedOperationException if this method is invoked.
1380      * @see java.util.Iterator
1381      */
1382     public void remove() {
1383         throw new UnsupportedOperationException();
1384     }
1385 
1386     /**
1387      * Returns true if the next token matches the pattern constructed from the
1388      * specified string. The scanner does not advance past any input.
1389      *
1390      * <p> An invocation of this method of the form {@code hasNext(pattern)}
1391      * behaves in exactly the same way as the invocation
1392      * {@code hasNext(Pattern.compile(pattern))}.
1393      *
1394      * @param pattern a string specifying the pattern to scan
1395      * @return true if and only if this scanner has another token matching
1396      *         the specified pattern
1397      * @throws IllegalStateException if this scanner is closed
1398      */
1399     public boolean hasNext(String pattern)  {
1400         return hasNext(patternCache.forName(pattern));
1401     }
1402 
1403     /**
1404      * Returns the next token if it matches the pattern constructed from the
1405      * specified string.  If the match is successful, the scanner advances
1406      * past the input that matched the pattern.
1407      *
1408      * <p> An invocation of this method of the form {@code next(pattern)}
1409      * behaves in exactly the same way as the invocation
1410      * {@code next(Pattern.compile(pattern))}.
1411      *
1412      * @param pattern a string specifying the pattern to scan
1413      * @return the next token
1414      * @throws NoSuchElementException if no such tokens are available
1415      * @throws IllegalStateException if this scanner is closed
1416      */
1417     public String next(String pattern)  {
1418         return next(patternCache.forName(pattern));
1419     }
1420 
1421     /**
1422      * Returns true if the next complete token matches the specified pattern.
1423      * A complete token is prefixed and postfixed by input that matches
1424      * the delimiter pattern. This method may block while waiting for input.
1425      * The scanner does not advance past any input.
1426      *
1427      * @param pattern the pattern to scan for
1428      * @return true if and only if this scanner has another token matching
1429      *         the specified pattern
1430      * @throws IllegalStateException if this scanner is closed


1435             throw new NullPointerException();
1436         hasNextPattern = null;
1437         saveState();
1438 
1439         while (true) {
1440             if (getCompleteTokenInBuffer(pattern) != null) {
1441                 matchValid = true;
1442                 cacheResult();
1443                 return revertState(true);
1444             }
1445             if (needInput)
1446                 readInput();
1447             else
1448                 return revertState(false);
1449         }
1450     }
1451 
1452     /**
1453      * Returns the next token if it matches the specified pattern. This
1454      * method may block while waiting for input to scan, even if a previous
1455      * invocation of {@link #hasNext(Pattern)} returned {@code true}.
1456      * If the match is successful, the scanner advances past the input that
1457      * matched the pattern.
1458      *
1459      * @param pattern the pattern to scan for
1460      * @return the next token
1461      * @throws NoSuchElementException if no more tokens are available
1462      * @throws IllegalStateException if this scanner is closed
1463      */
1464     public String next(Pattern pattern) {
1465         ensureOpen();
1466         if (pattern == null)
1467             throw new NullPointerException();
1468 
1469         // Did we already find this pattern?
1470         if (hasNextPattern == pattern)
1471             return getCachedResult();
1472         clearCaches();
1473 
1474         // Search for the pattern
1475         while (true) {


1537 
1538         String result = findWithinHorizon(linePattern, 0);
1539         if (result == null)
1540             throw new NoSuchElementException("No line found");
1541         MatchResult mr = this.match();
1542         String lineSep = mr.group(1);
1543         if (lineSep != null)
1544             result = result.substring(0, result.length() - lineSep.length());
1545         if (result == null)
1546             throw new NoSuchElementException();
1547         else
1548             return result;
1549     }
1550 
1551     // Public methods that ignore delimiters
1552 
1553     /**
1554      * Attempts to find the next occurrence of a pattern constructed from the
1555      * specified string, ignoring delimiters.
1556      *
1557      * <p>An invocation of this method of the form {@code findInLine(pattern)}
1558      * behaves in exactly the same way as the invocation
1559      * {@code findInLine(Pattern.compile(pattern))}.
1560      *
1561      * @param pattern a string specifying the pattern to search for
1562      * @return the text that matched the specified pattern
1563      * @throws IllegalStateException if this scanner is closed
1564      */
1565     public String findInLine(String pattern) {
1566         return findInLine(patternCache.forName(pattern));
1567     }
1568 
1569     /**
1570      * Attempts to find the next occurrence of the specified pattern ignoring
1571      * delimiters. If the pattern is found before the next line separator, the
1572      * scanner advances past the input that matched and returns the string that
1573      * matched the pattern.
1574      * If no such pattern is detected in the input up to the next line
1575      * separator, then {@code null} is returned and the scanner's
1576      * position is unchanged. This method may block waiting for input that
1577      * matches the pattern.
1578      *
1579      * <p>Since this method continues to search through the input looking
1580      * for the specified pattern, it may buffer all of the input searching for
1581      * the desired token if no line separators are present.
1582      *
1583      * @param pattern the pattern to scan for
1584      * @return the text that matched the specified pattern
1585      * @throws IllegalStateException if this scanner is closed
1586      */
1587     public String findInLine(Pattern pattern) {
1588         ensureOpen();
1589         if (pattern == null)
1590             throw new NullPointerException();
1591         clearCaches();
1592         // Expand buffer to include the next newline or end of input
1593         int endPosition = 0;
1594         saveState();
1595         while (true) {


1604                 endPosition = buf.limit();
1605                 break; // up to end of input
1606             }
1607         }
1608         revertState();
1609         int horizonForLine = endPosition - position;
1610         // If there is nothing between the current pos and the next
1611         // newline simply return null, invoking findWithinHorizon
1612         // with "horizon=0" will scan beyond the line bound.
1613         if (horizonForLine == 0)
1614             return null;
1615         // Search for the pattern
1616         return findWithinHorizon(pattern, horizonForLine);
1617     }
1618 
1619     /**
1620      * Attempts to find the next occurrence of a pattern constructed from the
1621      * specified string, ignoring delimiters.
1622      *
1623      * <p>An invocation of this method of the form
1624      * {@code findWithinHorizon(pattern)} behaves in exactly the same way as
1625      * the invocation
1626      * {@code findWithinHorizon(Pattern.compile(pattern, horizon))}.
1627      *
1628      * @param pattern a string specifying the pattern to search for
1629      * @param horizon the search horizon
1630      * @return the text that matched the specified pattern
1631      * @throws IllegalStateException if this scanner is closed
1632      * @throws IllegalArgumentException if horizon is negative
1633      */
1634     public String findWithinHorizon(String pattern, int horizon) {
1635         return findWithinHorizon(patternCache.forName(pattern), horizon);
1636     }
1637 
1638     /**
1639      * Attempts to find the next occurrence of the specified pattern.
1640      *
1641      * <p>This method searches through the input up to the specified
1642      * search horizon, ignoring delimiters. If the pattern is found the
1643      * scanner advances past the input that matched and returns the string
1644      * that matched the pattern. If no such pattern is detected then the
1645      * null is returned and the scanner's position remains unchanged. This
1646      * method may block waiting for input that matches the pattern.
1647      *
1648      * <p>A scanner will never search more than {@code horizon} code
1649      * points beyond its current position. Note that a match may be clipped
1650      * by the horizon; that is, an arbitrary match result may have been
1651      * different if the horizon had been larger. The scanner treats the
1652      * horizon as a transparent, non-anchoring bound (see {@link
1653      * Matcher#useTransparentBounds} and {@link Matcher#useAnchoringBounds}).
1654      *
1655      * <p>If horizon is {@code 0}, then the horizon is ignored and
1656      * this method continues to search through the input looking for the
1657      * specified pattern without bound. In this case it may buffer all of
1658      * the input searching for the pattern.
1659      *
1660      * <p>If horizon is negative, then an IllegalArgumentException is
1661      * thrown.
1662      *
1663      * @param pattern the pattern to scan for
1664      * @param horizon the search horizon
1665      * @return the text that matched the specified pattern
1666      * @throws IllegalStateException if this scanner is closed
1667      * @throws IllegalArgumentException if horizon is negative
1668      */
1669     public String findWithinHorizon(Pattern pattern, int horizon) {
1670         ensureOpen();
1671         if (pattern == null)
1672             throw new NullPointerException();
1673         if (horizon < 0)
1674             throw new IllegalArgumentException("horizon < 0");
1675         clearCaches();


1679             String token = findPatternInBuffer(pattern, horizon);
1680             if (token != null) {
1681                 matchValid = true;
1682                 return token;
1683             }
1684             if (needInput)
1685                 readInput();
1686             else
1687                 break; // up to end of input
1688         }
1689         return null;
1690     }
1691 
1692     /**
1693      * Skips input that matches the specified pattern, ignoring delimiters.
1694      * This method will skip input if an anchored match of the specified
1695      * pattern succeeds.
1696      *
1697      * <p>If a match to the specified pattern is not found at the
1698      * current position, then no input is skipped and a
1699      * {@code NoSuchElementException} is thrown.
1700      *
1701      * <p>Since this method seeks to match the specified pattern starting at
1702      * the scanner's current position, patterns that can match a lot of
1703      * input (".*", for example) may cause the scanner to buffer a large
1704      * amount of input.
1705      *
1706      * <p>Note that it is possible to skip something without risking a
1707      * {@code NoSuchElementException} by using a pattern that can
1708      * match nothing, e.g., {@code sc.skip("[ \t]*")}.
1709      *
1710      * @param pattern a string specifying the pattern to skip over
1711      * @return this scanner
1712      * @throws NoSuchElementException if the specified pattern is not found
1713      * @throws IllegalStateException if this scanner is closed
1714      */
1715     public Scanner skip(Pattern pattern) {
1716         ensureOpen();
1717         if (pattern == null)
1718             throw new NullPointerException();
1719         clearCaches();
1720 
1721         // Search for the pattern
1722         while (true) {
1723             String token = matchPatternInBuffer(pattern);
1724             if (token != null) {
1725                 matchValid = true;
1726                 position = matcher.end();
1727                 return this;
1728             }
1729             if (needInput)
1730                 readInput();
1731             else
1732                 throw new NoSuchElementException();
1733         }
1734     }
1735 
1736     /**
1737      * Skips input that matches a pattern constructed from the specified
1738      * string.
1739      *
1740      * <p> An invocation of this method of the form {@code skip(pattern)}
1741      * behaves in exactly the same way as the invocation
1742      * {@code skip(Pattern.compile(pattern))}.
1743      *
1744      * @param pattern a string specifying the pattern to skip over
1745      * @return this scanner
1746      * @throws IllegalStateException if this scanner is closed
1747      */
1748     public Scanner skip(String pattern) {
1749         return skip(patternCache.forName(pattern));
1750     }
1751 
1752     // Convenience methods for scanning primitives
1753 
1754     /**
1755      * Returns true if the next token in this scanner's input can be
1756      * interpreted as a boolean value using a case insensitive pattern
1757      * created from the string "true|false".  The scanner does not
1758      * advance past the input that matched.
1759      *
1760      * @return true if and only if this scanner's next token is a valid
1761      *         boolean value
1762      * @throws IllegalStateException if this scanner is closed
1763      */
1764     public boolean hasNextBoolean()  {
1765         return hasNext(boolPattern());
1766     }
1767 
1768     /**
1769      * Scans the next token of the input into a boolean value and returns
1770      * that value. This method will throw {@code InputMismatchException}
1771      * if the next token cannot be translated into a valid boolean value.
1772      * If the match is successful, the scanner advances past the input that
1773      * matched.
1774      *
1775      * @return the boolean scanned from the input
1776      * @throws InputMismatchException if the next token is not a valid boolean
1777      * @throws NoSuchElementException if input is exhausted
1778      * @throws IllegalStateException if this scanner is closed
1779      */
1780     public boolean nextBoolean()  {
1781         clearCaches();
1782         return Boolean.parseBoolean(next(boolPattern()));
1783     }
1784 
1785     /**
1786      * Returns true if the next token in this scanner's input can be
1787      * interpreted as a byte value in the default radix using the
1788      * {@link #nextByte} method. The scanner does not advance past any input.
1789      *
1790      * @return true if and only if this scanner's next token is a valid


1805      *         byte value
1806      * @throws IllegalStateException if this scanner is closed
1807      */
1808     public boolean hasNextByte(int radix) {
1809         setRadix(radix);
1810         boolean result = hasNext(integerPattern());
1811         if (result) { // Cache it
1812             try {
1813                 String s = (matcher.group(SIMPLE_GROUP_INDEX) == null) ?
1814                     processIntegerToken(hasNextResult) :
1815                     hasNextResult;
1816                 typeCache = Byte.parseByte(s, radix);
1817             } catch (NumberFormatException nfe) {
1818                 result = false;
1819             }
1820         }
1821         return result;
1822     }
1823 
1824     /**
1825      * Scans the next token of the input as a {@code byte}.
1826      *
1827      * <p> An invocation of this method of the form
1828      * {@code nextByte()} behaves in exactly the same way as the
1829      * invocation {@code nextByte(radix)}, where {@code radix}
1830      * is the default radix of this scanner.
1831      *
1832      * @return the {@code byte} scanned from the input
1833      * @throws InputMismatchException
1834      *         if the next token does not match the <i>Integer</i>
1835      *         regular expression, or is out of range
1836      * @throws NoSuchElementException if input is exhausted
1837      * @throws IllegalStateException if this scanner is closed
1838      */
1839     public byte nextByte() {
1840          return nextByte(defaultRadix);
1841     }
1842 
1843     /**
1844      * Scans the next token of the input as a {@code byte}.
1845      * This method will throw {@code InputMismatchException}
1846      * if the next token cannot be translated into a valid byte value as
1847      * described below. If the translation is successful, the scanner advances
1848      * past the input that matched.
1849      *
1850      * <p> If the next token matches the <a
1851      * href="#Integer-regex"><i>Integer</i></a> regular expression defined
1852      * above then the token is converted into a {@code byte} value as if by
1853      * removing all locale specific prefixes, group separators, and locale
1854      * specific suffixes, then mapping non-ASCII digits into ASCII
1855      * digits via {@link Character#digit Character.digit}, prepending a
1856      * negative sign (-) if the locale specific negative prefixes and suffixes
1857      * were present, and passing the resulting string to
1858      * {@link Byte#parseByte(String, int) Byte.parseByte} with the
1859      * specified radix.
1860      *
1861      * @param radix the radix used to interpret the token as a byte value
1862      * @return the {@code byte} scanned from the input
1863      * @throws InputMismatchException
1864      *         if the next token does not match the <i>Integer</i>
1865      *         regular expression, or is out of range
1866      * @throws NoSuchElementException if input is exhausted
1867      * @throws IllegalStateException if this scanner is closed
1868      */
1869     public byte nextByte(int radix) {
1870         // Check cached result
1871         if ((typeCache != null) && (typeCache instanceof Byte)
1872             && this.radix == radix) {
1873             byte val = ((Byte)typeCache).byteValue();
1874             useTypeCache();
1875             return val;
1876         }
1877         setRadix(radix);
1878         clearCaches();
1879         // Search for next byte
1880         try {
1881             String s = next(integerPattern());
1882             if (matcher.group(SIMPLE_GROUP_INDEX) == null)


1911      *         short value in the specified radix
1912      * @throws IllegalStateException if this scanner is closed
1913      */
1914     public boolean hasNextShort(int radix) {
1915         setRadix(radix);
1916         boolean result = hasNext(integerPattern());
1917         if (result) { // Cache it
1918             try {
1919                 String s = (matcher.group(SIMPLE_GROUP_INDEX) == null) ?
1920                     processIntegerToken(hasNextResult) :
1921                     hasNextResult;
1922                 typeCache = Short.parseShort(s, radix);
1923             } catch (NumberFormatException nfe) {
1924                 result = false;
1925             }
1926         }
1927         return result;
1928     }
1929 
1930     /**
1931      * Scans the next token of the input as a {@code short}.
1932      *
1933      * <p> An invocation of this method of the form
1934      * {@code nextShort()} behaves in exactly the same way as the
1935      * invocation {@code nextShort(radix)}, where {@code radix}
1936      * is the default radix of this scanner.
1937      *
1938      * @return the {@code short} scanned from the input
1939      * @throws InputMismatchException
1940      *         if the next token does not match the <i>Integer</i>
1941      *         regular expression, or is out of range
1942      * @throws NoSuchElementException if input is exhausted
1943      * @throws IllegalStateException if this scanner is closed
1944      */
1945     public short nextShort() {
1946         return nextShort(defaultRadix);
1947     }
1948 
1949     /**
1950      * Scans the next token of the input as a {@code short}.
1951      * This method will throw {@code InputMismatchException}
1952      * if the next token cannot be translated into a valid short value as
1953      * described below. If the translation is successful, the scanner advances
1954      * past the input that matched.
1955      *
1956      * <p> If the next token matches the <a
1957      * href="#Integer-regex"><i>Integer</i></a> regular expression defined
1958      * above then the token is converted into a {@code short} value as if by
1959      * removing all locale specific prefixes, group separators, and locale
1960      * specific suffixes, then mapping non-ASCII digits into ASCII
1961      * digits via {@link Character#digit Character.digit}, prepending a
1962      * negative sign (-) if the locale specific negative prefixes and suffixes
1963      * were present, and passing the resulting string to
1964      * {@link Short#parseShort(String, int) Short.parseShort} with the
1965      * specified radix.
1966      *
1967      * @param radix the radix used to interpret the token as a short value
1968      * @return the {@code short} scanned from the input
1969      * @throws InputMismatchException
1970      *         if the next token does not match the <i>Integer</i>
1971      *         regular expression, or is out of range
1972      * @throws NoSuchElementException if input is exhausted
1973      * @throws IllegalStateException if this scanner is closed
1974      */
1975     public short nextShort(int radix) {
1976         // Check cached result
1977         if ((typeCache != null) && (typeCache instanceof Short)
1978             && this.radix == radix) {
1979             short val = ((Short)typeCache).shortValue();
1980             useTypeCache();
1981             return val;
1982         }
1983         setRadix(radix);
1984         clearCaches();
1985         // Search for next short
1986         try {
1987             String s = next(integerPattern());
1988             if (matcher.group(SIMPLE_GROUP_INDEX) == null)


2041     private String processIntegerToken(String token) {
2042         String result = token.replaceAll(""+groupSeparator, "");
2043         boolean isNegative = false;
2044         int preLen = negativePrefix.length();
2045         if ((preLen > 0) && result.startsWith(negativePrefix)) {
2046             isNegative = true;
2047             result = result.substring(preLen);
2048         }
2049         int sufLen = negativeSuffix.length();
2050         if ((sufLen > 0) && result.endsWith(negativeSuffix)) {
2051             isNegative = true;
2052             result = result.substring(result.length() - sufLen,
2053                                       result.length());
2054         }
2055         if (isNegative)
2056             result = "-" + result;
2057         return result;
2058     }
2059 
2060     /**
2061      * Scans the next token of the input as an {@code int}.
2062      *
2063      * <p> An invocation of this method of the form
2064      * {@code nextInt()} behaves in exactly the same way as the
2065      * invocation {@code nextInt(radix)}, where {@code radix}
2066      * is the default radix of this scanner.
2067      *
2068      * @return the {@code int} scanned from the input
2069      * @throws InputMismatchException
2070      *         if the next token does not match the <i>Integer</i>
2071      *         regular expression, or is out of range
2072      * @throws NoSuchElementException if input is exhausted
2073      * @throws IllegalStateException if this scanner is closed
2074      */
2075     public int nextInt() {
2076         return nextInt(defaultRadix);
2077     }
2078 
2079     /**
2080      * Scans the next token of the input as an {@code int}.
2081      * This method will throw {@code InputMismatchException}
2082      * if the next token cannot be translated into a valid int value as
2083      * described below. If the translation is successful, the scanner advances
2084      * past the input that matched.
2085      *
2086      * <p> If the next token matches the <a
2087      * href="#Integer-regex"><i>Integer</i></a> regular expression defined
2088      * above then the token is converted into an {@code int} value as if by
2089      * removing all locale specific prefixes, group separators, and locale
2090      * specific suffixes, then mapping non-ASCII digits into ASCII
2091      * digits via {@link Character#digit Character.digit}, prepending a
2092      * negative sign (-) if the locale specific negative prefixes and suffixes
2093      * were present, and passing the resulting string to
2094      * {@link Integer#parseInt(String, int) Integer.parseInt} with the
2095      * specified radix.
2096      *
2097      * @param radix the radix used to interpret the token as an int value
2098      * @return the {@code int} scanned from the input
2099      * @throws InputMismatchException
2100      *         if the next token does not match the <i>Integer</i>
2101      *         regular expression, or is out of range
2102      * @throws NoSuchElementException if input is exhausted
2103      * @throws IllegalStateException if this scanner is closed
2104      */
2105     public int nextInt(int radix) {
2106         // Check cached result
2107         if ((typeCache != null) && (typeCache instanceof Integer)
2108             && this.radix == radix) {
2109             int val = ((Integer)typeCache).intValue();
2110             useTypeCache();
2111             return val;
2112         }
2113         setRadix(radix);
2114         clearCaches();
2115         // Search for next int
2116         try {
2117             String s = next(integerPattern());
2118             if (matcher.group(SIMPLE_GROUP_INDEX) == null)


2147      *         long value
2148      * @throws IllegalStateException if this scanner is closed
2149      */
2150     public boolean hasNextLong(int radix) {
2151         setRadix(radix);
2152         boolean result = hasNext(integerPattern());
2153         if (result) { // Cache it
2154             try {
2155                 String s = (matcher.group(SIMPLE_GROUP_INDEX) == null) ?
2156                     processIntegerToken(hasNextResult) :
2157                     hasNextResult;
2158                 typeCache = Long.parseLong(s, radix);
2159             } catch (NumberFormatException nfe) {
2160                 result = false;
2161             }
2162         }
2163         return result;
2164     }
2165 
2166     /**
2167      * Scans the next token of the input as a {@code long}.
2168      *
2169      * <p> An invocation of this method of the form
2170      * {@code nextLong()} behaves in exactly the same way as the
2171      * invocation {@code nextLong(radix)}, where {@code radix}
2172      * is the default radix of this scanner.
2173      *
2174      * @return the {@code long} scanned from the input
2175      * @throws InputMismatchException
2176      *         if the next token does not match the <i>Integer</i>
2177      *         regular expression, or is out of range
2178      * @throws NoSuchElementException if input is exhausted
2179      * @throws IllegalStateException if this scanner is closed
2180      */
2181     public long nextLong() {
2182         return nextLong(defaultRadix);
2183     }
2184 
2185     /**
2186      * Scans the next token of the input as a {@code long}.
2187      * This method will throw {@code InputMismatchException}
2188      * if the next token cannot be translated into a valid long value as
2189      * described below. If the translation is successful, the scanner advances
2190      * past the input that matched.
2191      *
2192      * <p> If the next token matches the <a
2193      * href="#Integer-regex"><i>Integer</i></a> regular expression defined
2194      * above then the token is converted into a {@code long} value as if by
2195      * removing all locale specific prefixes, group separators, and locale
2196      * specific suffixes, then mapping non-ASCII digits into ASCII
2197      * digits via {@link Character#digit Character.digit}, prepending a
2198      * negative sign (-) if the locale specific negative prefixes and suffixes
2199      * were present, and passing the resulting string to
2200      * {@link Long#parseLong(String, int) Long.parseLong} with the
2201      * specified radix.
2202      *
2203      * @param radix the radix used to interpret the token as an int value
2204      * @return the {@code long} scanned from the input
2205      * @throws InputMismatchException
2206      *         if the next token does not match the <i>Integer</i>
2207      *         regular expression, or is out of range
2208      * @throws NoSuchElementException if input is exhausted
2209      * @throws IllegalStateException if this scanner is closed
2210      */
2211     public long nextLong(int radix) {
2212         // Check cached result
2213         if ((typeCache != null) && (typeCache instanceof Long)
2214             && this.radix == radix) {
2215             long val = ((Long)typeCache).longValue();
2216             useTypeCache();
2217             return val;
2218         }
2219         setRadix(radix);
2220         clearCaches();
2221         try {
2222             String s = next(integerPattern());
2223             if (matcher.group(SIMPLE_GROUP_INDEX) == null)
2224                 s = processIntegerToken(s);


2289      *
2290      * @return true if and only if this scanner's next token is a valid
2291      *         float value
2292      * @throws IllegalStateException if this scanner is closed
2293      */
2294     public boolean hasNextFloat() {
2295         setRadix(10);
2296         boolean result = hasNext(floatPattern());
2297         if (result) { // Cache it
2298             try {
2299                 String s = processFloatToken(hasNextResult);
2300                 typeCache = Float.valueOf(Float.parseFloat(s));
2301             } catch (NumberFormatException nfe) {
2302                 result = false;
2303             }
2304         }
2305         return result;
2306     }
2307 
2308     /**
2309      * Scans the next token of the input as a {@code float}.
2310      * This method will throw {@code InputMismatchException}
2311      * if the next token cannot be translated into a valid float value as
2312      * described below. If the translation is successful, the scanner advances
2313      * past the input that matched.
2314      *
2315      * <p> If the next token matches the <a
2316      * href="#Float-regex"><i>Float</i></a> regular expression defined above
2317      * then the token is converted into a {@code float} value as if by
2318      * removing all locale specific prefixes, group separators, and locale
2319      * specific suffixes, then mapping non-ASCII digits into ASCII
2320      * digits via {@link Character#digit Character.digit}, prepending a
2321      * negative sign (-) if the locale specific negative prefixes and suffixes
2322      * were present, and passing the resulting string to
2323      * {@link Float#parseFloat Float.parseFloat}. If the token matches
2324      * the localized NaN or infinity strings, then either "Nan" or "Infinity"
2325      * is passed to {@link Float#parseFloat(String) Float.parseFloat} as
2326      * appropriate.
2327      *
2328      * @return the {@code float} scanned from the input
2329      * @throws InputMismatchException
2330      *         if the next token does not match the <i>Float</i>
2331      *         regular expression, or is out of range
2332      * @throws NoSuchElementException if input is exhausted
2333      * @throws IllegalStateException if this scanner is closed
2334      */
2335     public float nextFloat() {
2336         // Check cached result
2337         if ((typeCache != null) && (typeCache instanceof Float)) {
2338             float val = ((Float)typeCache).floatValue();
2339             useTypeCache();
2340             return val;
2341         }
2342         setRadix(10);
2343         clearCaches();
2344         try {
2345             return Float.parseFloat(processFloatToken(next(floatPattern())));
2346         } catch (NumberFormatException nfe) {
2347             position = matcher.start(); // don't skip bad token
2348             throw new InputMismatchException(nfe.getMessage());


2356      *
2357      * @return true if and only if this scanner's next token is a valid
2358      *         double value
2359      * @throws IllegalStateException if this scanner is closed
2360      */
2361     public boolean hasNextDouble() {
2362         setRadix(10);
2363         boolean result = hasNext(floatPattern());
2364         if (result) { // Cache it
2365             try {
2366                 String s = processFloatToken(hasNextResult);
2367                 typeCache = Double.valueOf(Double.parseDouble(s));
2368             } catch (NumberFormatException nfe) {
2369                 result = false;
2370             }
2371         }
2372         return result;
2373     }
2374 
2375     /**
2376      * Scans the next token of the input as a {@code double}.
2377      * This method will throw {@code InputMismatchException}
2378      * if the next token cannot be translated into a valid double value.
2379      * If the translation is successful, the scanner advances past the input
2380      * that matched.
2381      *
2382      * <p> If the next token matches the <a
2383      * href="#Float-regex"><i>Float</i></a> regular expression defined above
2384      * then the token is converted into a {@code double} value as if by
2385      * removing all locale specific prefixes, group separators, and locale
2386      * specific suffixes, then mapping non-ASCII digits into ASCII
2387      * digits via {@link Character#digit Character.digit}, prepending a
2388      * negative sign (-) if the locale specific negative prefixes and suffixes
2389      * were present, and passing the resulting string to
2390      * {@link Double#parseDouble Double.parseDouble}. If the token matches
2391      * the localized NaN or infinity strings, then either "Nan" or "Infinity"
2392      * is passed to {@link Double#parseDouble(String) Double.parseDouble} as
2393      * appropriate.
2394      *
2395      * @return the {@code double} scanned from the input
2396      * @throws InputMismatchException
2397      *         if the next token does not match the <i>Float</i>
2398      *         regular expression, or is out of range
2399      * @throws NoSuchElementException if the input is exhausted
2400      * @throws IllegalStateException if this scanner is closed
2401      */
2402     public double nextDouble() {
2403         // Check cached result
2404         if ((typeCache != null) && (typeCache instanceof Double)) {
2405             double val = ((Double)typeCache).doubleValue();
2406             useTypeCache();
2407             return val;
2408         }
2409         setRadix(10);
2410         clearCaches();
2411         // Search for next float
2412         try {
2413             return Double.parseDouble(processFloatToken(next(floatPattern())));
2414         } catch (NumberFormatException nfe) {
2415             position = matcher.start(); // don't skip bad token
2416             throw new InputMismatchException(nfe.getMessage());
2417         }
2418     }
2419 
2420     // Convenience methods for scanning multi precision numbers
2421 
2422     /**
2423      * Returns true if the next token in this scanner's input can be
2424      * interpreted as a {@code BigInteger} in the default radix using the
2425      * {@link #nextBigInteger} method. The scanner does not advance past any
2426      * input.
2427      *
2428      * @return true if and only if this scanner's next token is a valid
2429      *         {@code BigInteger}
2430      * @throws IllegalStateException if this scanner is closed
2431      */
2432     public boolean hasNextBigInteger() {
2433         return hasNextBigInteger(defaultRadix);
2434     }
2435 
2436     /**
2437      * Returns true if the next token in this scanner's input can be
2438      * interpreted as a {@code BigInteger} in the specified radix using
2439      * the {@link #nextBigInteger} method. The scanner does not advance past
2440      * any input.
2441      *
2442      * @param radix the radix used to interpret the token as an integer
2443      * @return true if and only if this scanner's next token is a valid
2444      *         {@code BigInteger}
2445      * @throws IllegalStateException if this scanner is closed
2446      */
2447     public boolean hasNextBigInteger(int radix) {
2448         setRadix(radix);
2449         boolean result = hasNext(integerPattern());
2450         if (result) { // Cache it
2451             try {
2452                 String s = (matcher.group(SIMPLE_GROUP_INDEX) == null) ?
2453                     processIntegerToken(hasNextResult) :
2454                     hasNextResult;
2455                 typeCache = new BigInteger(s, radix);
2456             } catch (NumberFormatException nfe) {
2457                 result = false;
2458             }
2459         }
2460         return result;
2461     }
2462 
2463     /**
2464      * Scans the next token of the input as a {@link java.math.BigInteger
2465      * BigInteger}.
2466      *
2467      * <p> An invocation of this method of the form
2468      * {@code nextBigInteger()} behaves in exactly the same way as the
2469      * invocation {@code nextBigInteger(radix)}, where {@code radix}
2470      * is the default radix of this scanner.
2471      *
2472      * @return the {@code BigInteger} scanned from the input
2473      * @throws InputMismatchException
2474      *         if the next token does not match the <i>Integer</i>
2475      *         regular expression, or is out of range
2476      * @throws NoSuchElementException if the input is exhausted
2477      * @throws IllegalStateException if this scanner is closed
2478      */
2479     public BigInteger nextBigInteger() {
2480         return nextBigInteger(defaultRadix);
2481     }
2482 
2483     /**
2484      * Scans the next token of the input as a {@link java.math.BigInteger
2485      * BigInteger}.
2486      *
2487      * <p> If the next token matches the <a
2488      * href="#Integer-regex"><i>Integer</i></a> regular expression defined
2489      * above then the token is converted into a {@code BigInteger} value as if
2490      * by removing all group separators, mapping non-ASCII digits into ASCII
2491      * digits via the {@link Character#digit Character.digit}, and passing the
2492      * resulting string to the {@link
2493      * java.math.BigInteger#BigInteger(java.lang.String)
2494      * BigInteger(String, int)} constructor with the specified radix.
2495      *
2496      * @param radix the radix used to interpret the token
2497      * @return the {@code BigInteger} scanned from the input
2498      * @throws InputMismatchException
2499      *         if the next token does not match the <i>Integer</i>
2500      *         regular expression, or is out of range
2501      * @throws NoSuchElementException if the input is exhausted
2502      * @throws IllegalStateException if this scanner is closed
2503      */
2504     public BigInteger nextBigInteger(int radix) {
2505         // Check cached result
2506         if ((typeCache != null) && (typeCache instanceof BigInteger)
2507             && this.radix == radix) {
2508             BigInteger val = (BigInteger)typeCache;
2509             useTypeCache();
2510             return val;
2511         }
2512         setRadix(radix);
2513         clearCaches();
2514         // Search for next int
2515         try {
2516             String s = next(integerPattern());
2517             if (matcher.group(SIMPLE_GROUP_INDEX) == null)
2518                 s = processIntegerToken(s);
2519             return new BigInteger(s, radix);
2520         } catch (NumberFormatException nfe) {
2521             position = matcher.start(); // don't skip bad token
2522             throw new InputMismatchException(nfe.getMessage());
2523         }
2524     }
2525 
2526     /**
2527      * Returns true if the next token in this scanner's input can be
2528      * interpreted as a {@code BigDecimal} using the
2529      * {@link #nextBigDecimal} method. The scanner does not advance past any
2530      * input.
2531      *
2532      * @return true if and only if this scanner's next token is a valid
2533      *         {@code BigDecimal}
2534      * @throws IllegalStateException if this scanner is closed
2535      */
2536     public boolean hasNextBigDecimal() {
2537         setRadix(10);
2538         boolean result = hasNext(decimalPattern());
2539         if (result) { // Cache it
2540             try {
2541                 String s = processFloatToken(hasNextResult);
2542                 typeCache = new BigDecimal(s);
2543             } catch (NumberFormatException nfe) {
2544                 result = false;
2545             }
2546         }
2547         return result;
2548     }
2549 
2550     /**
2551      * Scans the next token of the input as a {@link java.math.BigDecimal
2552      * BigDecimal}.
2553      *
2554      * <p> If the next token matches the <a
2555      * href="#Decimal-regex"><i>Decimal</i></a> regular expression defined
2556      * above then the token is converted into a {@code BigDecimal} value as if
2557      * by removing all group separators, mapping non-ASCII digits into ASCII
2558      * digits via the {@link Character#digit Character.digit}, and passing the
2559      * resulting string to the {@link
2560      * java.math.BigDecimal#BigDecimal(java.lang.String) BigDecimal(String)}
2561      * constructor.
2562      *
2563      * @return the {@code BigDecimal} scanned from the input
2564      * @throws InputMismatchException
2565      *         if the next token does not match the <i>Decimal</i>
2566      *         regular expression, or is out of range
2567      * @throws NoSuchElementException if the input is exhausted
2568      * @throws IllegalStateException if this scanner is closed
2569      */
2570     public BigDecimal nextBigDecimal() {
2571         // Check cached result
2572         if ((typeCache != null) && (typeCache instanceof BigDecimal)) {
2573             BigDecimal val = (BigDecimal)typeCache;
2574             useTypeCache();
2575             return val;
2576         }
2577         setRadix(10);
2578         clearCaches();
2579         // Search for next float
2580         try {
2581             String s = processFloatToken(next(decimalPattern()));
2582             return new BigDecimal(s);
2583         } catch (NumberFormatException nfe) {
2584             position = matcher.start(); // don't skip bad token
2585             throw new InputMismatchException(nfe.getMessage());
2586         }
2587     }
2588 
2589     /**
2590      * Resets this scanner.
2591      *
2592      * <p> Resetting a scanner discards all of its explicit state
2593      * information which may have been changed by invocations of {@link
2594      * #useDelimiter}, {@link #useLocale}, or {@link #useRadix}.
2595      *
2596      * <p> An invocation of this method of the form
2597      * {@code scanner.reset()} behaves in exactly the same way as the
2598      * invocation
2599      *
2600      * <blockquote><pre>{@code
2601      *   scanner.useDelimiter("\\p{javaWhitespace}+")
2602      *          .useLocale(Locale.getDefault(Locale.Category.FORMAT))
2603      *          .useRadix(10);
2604      * }</pre></blockquote>
2605      *
2606      * @return this scanner
2607      *
2608      * @since 1.6
2609      */
2610     public Scanner reset() {
2611         delimPattern = WHITESPACE_PATTERN;
2612         useLocale(Locale.getDefault(Locale.Category.FORMAT));
2613         useRadix(10);
2614         clearCaches();
2615         return this;
2616     }
2617 }
< prev index next >