1

I am starting to code in Java (never done so before), and I am having a headache with input validation.

I need that while a user inputs numbers from 0 to 1000, the while loops keeps getting executed. That works fine. The problem is I would like to check wether he inputs a number, and if he doesn't, the while loop should keep executing and waiting for the next input. So far my code only throws InputMismatchException when inputting something that is not a number and I can't see why.

Here is my code:

Scanner score = new Scanner(System.in);
    int i = 0;
    while (i < 1000000) {
        System.out.print("Insert the new score: ");
        if (score.hasNextInt()) {
            i = score.nextInt();
            if (i > 0) {
                if (i < 200000) {
                    // do something
                } else if (i < 500000) {
                    // do something
                } else if (i < 700000) {
                    // do something
                } else if (i < 100001) {
                    // do something
                }
            } else if (i < 0) {
                // do something else
            }
        } else {
            System.out.print("The score should be a number.");
            i = score.nextInt();
        }
    }
Malt
  • 25,324
  • 9
  • 56
  • 86
ragtime.sp
  • 101
  • 1
  • 11
  • The program throws an `InputMismatchException` because `score.nextInt()` reads a number and when you type in input something that is not a number the exception is thrown – Maial Nov 28 '15 at 22:13
  • Check out this you will get your answer: http://stackoverflow.com/questions/15249578/exception-in-thread-main-java-util-inputmismatchexception-error – notescrew Nov 28 '15 at 22:15

5 Answers5

1
else{
    System.out.print("The score should be a number.");
    i = score.nextInt(); //<---problem
}

Here you know that input was not a number so you shouldn't be trying to read it as int with nextInt(). So to consume invalid data use

Pshemo
  • 113,402
  • 22
  • 170
  • 242
  • Thanks! I solved it thanks to this. I used: `score.next(); score.nextLine();` and it comes right at the beggining! – ragtime.sp Nov 30 '15 at 21:50
  • @ragtime.sp You are welcome. Anyway you probably don't need `score.next()` if you are using `score.nextLine()` since `nextLine()` will consume entire text until first line separation character it finds, so there is something strange about this solution (unless you are not talking about problem with consuming incorrect data, but problem linked at the end of my answer). – Pshemo Nov 30 '15 at 22:02
  • The thing is that using only `score.nextLine();` the program was expecting me to input a new value withuot showing `System.out.print("Insert the new score: ");` that It's at the beggining of the while loop. Using both combined it waits after showing that message. – ragtime.sp Nov 30 '15 at 22:19
  • @ragtime.sp OK, if it works for you then lets leave it (but I really don't feel like this `next` should be there). Anyway after seeing [list of your questions](http://stackoverflow.com/users/4108728/ragtime-sp?tab=questions) I don't see any accepted answers (except this one), so either there ware no answers which solved your problem or you simply didn't know about "accepting answer" mechanism. If it is the second case then you should probably visit your questions and if some answer solves it simply mark it as solution (or maybe ask author for corrections if answer isn't correct). – Pshemo Nov 30 '15 at 22:32
0

You are receiving this error because you're telling Scanner to get an integer, even when the user does not type an integer. You need to instead accept all input (via a String) and do the validation yourself.

I've modded your code to take input as a String (Scanner#nextLine) and then attempt to update the score.

Scanner score = new Scanner(System.in);
int i = 0;
while (i < 1000000) {
    System.out.print("Insert the new score: ");
    if (score.hasNext()) {
        final String input = score.nextLine();
        try {
            i = Integer.parseInt(input);
        } catch (final Exception e) {
            System.out.print("The score should be a number.");
            continue;
        }
    }
    if (i>0) {
        if (i<200000) {
            //do something
        }
        else if (i<500000) {
            //do something
        }
        else if (i<700000) {
            //do something
        }
        else if (i<100001) {
            //do something
        }
    } else if (i<0) {
        //do something else
    }
}

Note the continue; statement will indefinitely ask the user for integer input until the user does, just as you requested in your question.

Confiqure
  • 6,440
  • 13
  • 52
  • 78
0

In your final else clause, you call score.nextInt() although you know that the next number isn't an int. That's why you get the exception. Just replace the else with this:

else {
    System.out.print("The score should be a number.");
    score.nextLine(); //This is the line you need to change
}

score.nextLine(); will consume the next line of input safely, and put you back in the loop.

Malt
  • 25,324
  • 9
  • 56
  • 86
-1

You need to wrap your input statement inside a try/catch block and catch the InputMisMatchException. The InputMisMatchException happens because of using nextInt() in the Scanner which is expecting integer.

Scanner input = new Scanner(System.in);
int i = 0;
do {
    try {
        System.out.print("Enter integer ");
        i = input.nextInt();
    } catch (InputMismatchException e) {
       //anything but integer gets caught here.
        System.out.print("Please enter only integer.");
    }
    //necessary to take the cursor back to start of line, clear the buffer
     input.nextLine();

} while (i < 1000000);

Above code example shows how to catch the InputMisMatchException.

I noticed that you have use input.hasNextInt() in your code, and all you need is to replace the following in the else block of your code.

i = score.nextInt()

with

score.nextLine(); 

As described in other answers, this sentence will clear the buffer waiting for next input. The exception is due to score.nextInt(), the replacement should fix it.

Raf
  • 6,620
  • 1
  • 35
  • 54
-1

You may want to wrap while contents with try-catch block.

Scanner score = new Scanner(System.in);
int i = 0;
while (i < 1000000){
try{
    System.out.print("Insert the new score: ");
    if (score.hasNextInt()){
    i = score.nextInt();
    if (i>0){
        if (i<200000){
            do something
        }
        else if (i<500000){
            do something
        }
        else if (i<700000){
            do something
        }
        else if (i<100001){
            do something
        }
    }else if (i<0){
        do something else
    }
    }else{
        System.out.print("The score should be a number.");
        i = score.nextInt();
    }
}catch(Exception e){}
}
Yoda
  • 15,011
  • 59
  • 173
  • 291