-1

So I was using this code in my program and whenever I give input consisting of multiple words, the compiler executes the catch block that many times. I've also tried it with different methods & till now all efforts went to vain.

Method 1:

Scanner scanner = new Scanner(System.in);
int size = 0;
while (true) 
{
    try
    {
        size = scanner.nextInt();
        break;
    }
    catch (InputMismatchException e) 
    {
        System.out.println("Enter valid input (Digit Only)");
        scanner.next();
        continue;
    }
}

Method 2:

Scanner scanner = new Scanner(System.in);
int size = 0;
boolean bError = true;
while (bError) 
{
    if (scanner.hasNextInt())
        size = scanner.nextInt();
    else 
    {
        System.out.println("Enter valid input (Digit Only)");
        scanner.next();
        continue;
    }
    bError = false;
}

Method 3:

Scanner scanner = new Scanner(System.in);
int size = 0;
while (true) 
{
    if (scanner.hasNextInt())
    size = scanner.nextInt();
else 
{
    scanner.next();
    System.out.println("Enter valid input (Digit Only)");
continue;
}
String sizeStr = Integer.toString(size);
Pattern pattern = Pattern.compile(new String ("^[0-9]*$"));
Matcher matcher = pattern.matcher(sizeStr);
if(matcher.matches())
{    
    break;
}
else
{
    System.out.println("Enter valid input (Digit Only)");
    continue;
}
}

Method 4:

Scanner scanner = new Scanner(System.in);
int size = 0;
while (scanner.hasNext()) 
{
    if (scanner.hasNextInt())
    {
        size = scanner.nextInt();
        System.out.println(size);
        break;
    }
    else
    {
        System.out.println("Enter valid input (Digit Only)");
        scanner.next();
    }
}

I'm now able to do the task via taking a String input and then parsing it to int. But the initial doubt still remains that why that was not working properly. The code below is working fine.

Scanner scanner = new Scanner(System.in);
int size = 0;
while (true) 
{
    try
    {
        String sizeStr = scanner.nextLine();
        size = Integer.parseInt(sizeStr);
        break;
    }
    catch (NumberFormatException e) 
    {
        System.out.println("Enter valid input (Digit Only)");
        scanner.next();
        continue;
    }
}
Jaideep
  • 123
  • 1
  • 14

1 Answers1

0

According to the official Java Doc (https://docs.oracle.com/javase/8/docs/api/java/util/Scanner.html):

A Scanner breaks its input into tokens using a delimiter pattern, 
which by default matches whitespace. The resulting tokens may then be 
converted into values of different types using the various next 
methods.

The scanner can also use delimiters other than whitespace.

By default, all the next*() functions of scanner class other than nextLine() read the next token, not the next line. This means it reads until it finds a whitespace. If you want to read all the tokens in a line, you need to use nextLine() and then format the input explicitly as you want.

Consider this input:

abcd xyz

When you do scanner.nextInt() or any of scanner.next*() functions other than scanner.nextLine(), only "abcd" is read because it is the next token. When you do scanner.nextLine(), the complete string in the current line "abcd xyz" is read and the scanner advances to the next line.

However, if you want the nextInt() function to read the whole line, then you can set the delimiter to be new line '\n'.

Scanner scan = new Scanner(System.in).useDelimiter("\n");

Using this, you can get the behaviour that you want.

iavanish
  • 509
  • 3
  • 8