1

How can I check if the next three input user is giving is an int value, like let's say there is three variables,

  • var1
  • var2
  • var3

And I am taking input as,

Scanner sc = new Scanner (System.in); var1 = sc.nextInt(); var2 = sc.nextInt(); var3 = sc.nextInt();

Now if I want to use while(sc.hasNextInt()) to determine if the next input is an int or not then it will only check if the next input for var1 is int or not and won't check for the other to variables, var2, var3. One thing can be done by using while loop with if (condition). For example,

Scanner sc = new Scanner (System.in);
while (sc.hasNextInt()) {
   var1 = sc.nextInt();
   if (sc.hasNextInt()) {
      var2 = sc.nextInt();
      if (sc.hasNextInt()) {
         var3 = sc.nextInt();
      }
   }
 }

But this looks lengthy and needs a lot to write. For similar issue I have seen for Language C there is a method for scanf() which can do the trick. For example,

while(scanf("%d %d %d", &var1, &var2 & var3) == 3) { // Statements here }

So my question is there any such features available in java's Scanner.hasNextInt or Scanner.hasNext("regex").

I have also tried sc.hasNext("[0-9]* [0-9]* [0-9]*") but didn't worked actually.

Thank you in advance.

2 Answers2

2

hasNext(regex) tests only single token. Problem is that default delimiter is one-or-more-whitespaces so number number number can't be single token (delimiter - space - can't be part of it). So sc.hasNext("[0-9]* [0-9]* [0-9]*") each time will end up testing only single number. BTW in your pattern * should probably be + since each number should have at least one digit.

To let spaces be part of token we need to remove them from delimiter pattern. In other words we need to replace delimiter pattern with one which represents only line separators like \R (more info). This way if user will write data in one line (will use enter only after third number) that line would be seen as single token and can be tested by regex.

Later you will need to set delimiter back to one-or-more-whitespaces (\s+) because nextInt also works based on single token, so without it we would end up with trying to parse string like "1 2 3".

Scanner sc = new Scanner(System.in);
sc.useDelimiter("\\R");
System.out.print("Write 3 numbers (sepate them with space): ");
while(!sc.hasNext("\\d+ \\d+ \\d+")){
    String line = sc.nextLine();//IMPORTANT! Consume incorrect values
    System.out.println("This are not 3 numbers: "+line);
    System.out.print("Try again: ");
}
//here we are sure that there are 3 numbers
sc.useDelimiter("\\s+");//nextInt can't properly parse "num num num", we need to set whitespaces as delimiter

int var1 = sc.nextInt();
int var2 = sc.nextInt();
int var3 = sc.nextInt();

System.out.println("var1=" + var1);
System.out.println("var2=" + var2);
System.out.println("var3=" + var3);

Possible problem with this solution is fact that \d+ will let user provide number of any length, which may be out of int range. If you want to accept only int take a look at Regex for a valid 32-bit signed integer. You can also use nextLong instead, since long has larger range, but still it has max value. To accept any integer, regardless of its length you can use nextBigInteger().

Pshemo
  • 122,468
  • 25
  • 185
  • 269
0

I tried with nextLine method and usage of Pattern. Regex is matching with 3 numbers which is separeted with space. So it can be like this i think ;

Scanner scanner = new Scanner(System.in);

Pattern p = Pattern.compile("[0-9]+\\s[0-9]+\\s[0-9]+$");
while(!p.matcher(scanner.nextLine()).find()){
    System.out.println("Please write a 3 numbers which is separete with space");
}
System.out.println("Yes i got 3 numbers!");

I hope this helps you.

drowny
  • 2,067
  • 11
  • 19