Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
123 views
in Technique[技术] by (71.8m points)

java - How do I keep a Scanner from throwing exceptions when the wrong type is entered?

Here's some sample code:

import java.util.Scanner;
class In
{
    public static void main (String[]arg) 
    {
    Scanner in = new Scanner (System.in) ;
    System.out.println ("how many are invading?") ;
    int a = in.nextInt() ; 
    System.out.println (a) ; 
    } 
}

If I run the program and give it an int like 4, then everything goes fine.

On the other hand, if I answer too many it doesn't laugh at my funny joke. Instead I get this(as expected):

Exception in thread "main" java.util.InputMismatchException
    at java.util.Scanner.throwFor(Scanner.java:819)
    at java.util.Scanner.next(Scanner.java:1431)
    at java.util.Scanner.nextInt(Scanner.java:2040)
    at java.util.Scanner.nextInt(Scanner.java:2000)
    at In.main(In.java:9)

Is there a way to make it ignore entries that aren't ints or re prompt with "How many are invading?" I'd like to know how to do both of these.

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can use one of the many hasNext* methods that Scanner has for pre-validation.

    if (in.hasNextInt()) {
        int a = in.nextInt() ; 
        System.out.println(a);
    } else {
        System.out.println("Sorry, couldn't understand you!");
    }

This prevents InputMismatchException from even being thrown, because you always make sure that it WILL match before you read it.


java.util.Scanner API

  • boolean hasNextInt(): Returns true if the next token in this scanner's input can be interpreted as an int value in the default radix using the nextInt() method. The scanner does not advance past any input.

  • String nextLine(): Advances this scanner past the current line and returns the input that was skipped.

Do keep in mind the sections in bold. hasNextInt() doesn't advance past any input. If it returns true, you can advance the scanner by calling nextInt(), which will not throw an InputMismatchException.

If it returns false, then you need to skip past the "garbage". The easiest way to do this is just by calling nextLine(), probably twice but at least once.

Why you may need to do nextLine() twice is the following: suppose this is the input entered:

42[enter]
too many![enter]
0[enter]

Let's say the scanner is at the beginning of that input.

  • hasNextInt() is true, nextInt() returns 42; scanner is now at just before the first [enter].
  • hasNextInt() is false, nextLine() returns an empty string, a second nextLine() returns "too many!"; scanner is now at just after the second [enter].
  • hasNextInt() is true, nextInt() returns 0; scanner is now at just before the third [enter].

Here's an example of putting some of these things together. You can experiment with it to study how Scanner works.

        Scanner in = new Scanner (System.in) ;
        System.out.println("Age?");
        while (!in.hasNextInt()) {
            in.next(); // What happens if you use nextLine() instead?
        }
        int age = in.nextInt();
        in.nextLine(); // What happens if you remove this statement?
        
        System.out.println("Name?");
        String name = in.nextLine();
        
        System.out.format("[%s] is %d years old", name, age);

Let's say the input is:

He is probably close to 100 now...[enter]
Elvis, of course[enter]

Then the last line of the output is:

[Elvis, of course] is 100 years old

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...