catch block is running multiple times for InputMismatchException - java

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;
}
}

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.

Related

Ensuring user input is a single integer while using Scanner [duplicate]

This question already has answers here:
How do I ensure that Scanner hasNextInt() asks for new input?
(2 answers)
Closed 6 years ago.
Desired outcome:
Accepts user input
Makes sure user inputs only 1 integer value at a time
Stores that integer in a variable
I tried to achieve this by doing the following:
Store user input in variable
Count number of tokens in variable
If there's not one token, reject the input
If the input is not of data type int, reject the input
Code:
Scanner scan = new Scanner(System.in);
System.out.println("Enter an integer:");
String myString = scan.nextLine();
int tokens = new StringTokenizer(myString, " ").countTokens();
while (tokens != 1 && !scan.hasNextInt()) {
System.out.println("Enter a single integer");
myString = scanner.nextLine();
tokens = new StringTokenizer(myString, " ").countTokens();
}
int number = scanner.nextInt();
System.out.println(number);
This code is full of holes. The output is inconsistent and undesired. It typically ends by throwing a java.util.InputMismatchException error, indicating the value it's trying to store isn't an int. I've experienced this error occur after one loop and after multiple loops, even with the same type and quantity of input (e.g. 2 strings).
Should I keep going with this code, or should I try to approach this problem from a different angle?
I've modified your program a little bit. My approach was to accept a single line of input. If the input contains more than one token, ask the user to re-enter input. If there is only one input, check if the input is an integer, if not, as the user to again provide input.
Seems to work for me:
Scanner scanner = new Scanner(System.in);
String myString;
int tokens;
int number;
do {
System.out.println("Enter a single integer");
myString = scanner.nextLine();
tokens = new StringTokenizer(myString, " ").countTokens();
try {
number = Integer.parseInt(myString);
} catch(NumberFormatException e) {
tokens = 0;
number = -1;
}
}while (tokens != 1);
scanner.close();
System.out.println(number);
Update: Alternate approach without using StringTokenizer
Scanner scanner = new Scanner(System.in);
String myString;
boolean validInput;
int number;
do {
System.out.println("Enter a single integer");
myString = scanner.nextLine();
try {
number = Integer.parseInt(myString);
validInput = true;
} catch(NumberFormatException e) {
validInput = false;
number = -1;
}
}while (validInput == false);
scanner.close();
System.out.println(number);
Update 2: Another approach using regular expressions to validate input before accepting it.
The Scanner allows us to use a regular expression to match the input. If the input matches the pattern, you can use it to accept the input. Otherwise, discard it and ask user to provide input again.
Here's the code:
Scanner scanner = new Scanner(System.in);
System.out.println("Enter a single integer");
String integerPattern = "[+-]?\\d+$"; // positive or negative and digits only
while(scanner.hasNext(integerPattern) == false) {
String x = scanner.nextLine();// capture and discard input.
System.out.println("Enter a single integer. '" + x + "' is an invalid input.");
}
int number = scanner.nextInt(); // capture input only if it matches pattern.
scanner.close();
System.out.println("number: " + number);
Hope this helps!

Sanitizing user input in Java, correcting mistakes [duplicate]

I'm new to Java and I wanted to keep on asking for user input until the user enters an integer, so that there's no InputMismatchException. I've tried this code, but I still get the exception when I enter a non-integer value.
int getInt(String prompt){
System.out.print(prompt);
Scanner sc = new Scanner(System.in);
while(!sc.hasNextInt()){
System.out.println("Enter a whole number.");
sc.nextInt();
}
return sc.nextInt();
}
Thanks for your time!
Take the input using next instead of nextInt. Put a try catch to parse the input using parseInt method. If parsing is successful break the while loop, otherwise continue.
Try this:
System.out.print("input");
Scanner sc = new Scanner(System.in);
while (true) {
System.out.println("Enter a whole number.");
String input = sc.next();
int intInputValue = 0;
try {
intInputValue = Integer.parseInt(input);
System.out.println("Correct input, exit");
break;
} catch (NumberFormatException ne) {
System.out.println("Input is not a number, continue");
}
}
Shorter solution. Just take input in sc.next()
public int getInt(String prompt) {
Scanner sc = new Scanner(System.in);
System.out.print(prompt);
while (!sc.hasNextInt()) {
System.out.println("Enter a whole number");
sc.next();
}
return sc.nextInt();
}
Working on Juned's code, I was able to make it shorter.
int getInt(String prompt) {
System.out.print(prompt);
while(true){
try {
return Integer.parseInt(new Scanner(System.in).next());
} catch(NumberFormatException ne) {
System.out.print("That's not a whole number.\n"+prompt);
}
}
}
Keep gently scanning while you still have input, and check if it's indeed integer, as you need:
String s = "This is not yet number 10";
// create a new scanner
// with the specified String Object
Scanner scanner = new Scanner(s);
while (scanner.hasNext()) {
// if the next is a Int,
// print found and the Int
if (scanner.hasNextInt()) {
System.out.println("Found Int value :"
+ scanner.nextInt());
}
// if no Int is found,
// print "Not Found:" and the token
else {
System.out.println("Not found Int value :"
+ scanner.next());
}
}
scanner.close();
As an alternative, if it is just a single digit integer [0-9], then you can check its ASCII code. It should be between 48-57 to be an integer.
Building up on Juned's code, you can replace try block with an if condition:
System.out.print("input");
Scanner sc = new Scanner(System.in);
while (true) {
System.out.println("Enter a whole number.");
String input = sc.next();
int intInputValue = 0;
if(input.charAt(0) >= 48 && input.charAt(0) <= 57){
System.out.println("Correct input, exit");
break;
}
System.out.println("Input is not a number, continue");
}

Can we read and compare the value from the console in a single line?

Following is the piece of code i have used in c/c++ which is fairly simple:
while ((scanf_s("%d", &num) == 1)&&num>0)
Below is the usual java code to read input:
try(Scanner n1 = new Scanner(System.in))
{
System.out.println("Enter the number of days");
while(n1.hasNextInt())
{
days = n1.nextInt();
//some stmts
n1.nextLine();
}
}
How can use this while to read the input as well as compare the value in a single "while" like i can do in c and c++;
You could so something like this:
int num;
final Scanner scanner = new Scanner(System.in);
while (scanner.hasNextInt() && (num = scanner.nextInt()) > 0) {
// do something with num
}
Alternatively, you could do something like this:
int input;
final Scanner scanner = new Scanner(System.in);
System.out.print("Type anything: ");
try
{
input = scanner.nextInt();
System.out.println("You typed: " + input);
}
catch (InputMismatchException e)
{
System.out.println("You typed a non-numeric value or the value entered is out of range.");
}
You can handle the exception for cases where the input is not a number or out of range.

scanner does not work when I push enter

I am using java and I have a code as follow:
Scanner scanner = new Scanner(System.in);
while (true) {
String token = scanner.next();
if (token.equals("$")) break;
if (token.equals("(")) do sth;
else if (token.equals(")")) do sth;
else {
do sth
}
}
as you can see in the above code if you enter sth in the console then you enter $ at the end then the program will understand the end of input and the scanner can succesfully get each word of the string succesfully but instead I want when the user push enter then the scanner grabs the whole string and start reading it word by word I tried it this way :
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
String token = scanner.next();
if (token.equals("(")) builder.buildOpenBracket();
else if (token.equals(")")) builder.buildCloseBracket();
else {
int number = Integer.parseInt(token);
builder.buildElement(number);
}
}
but now the proram runs forever and nothing happends
Firstly, to read new line and save it in a String you should use .nextLine()
Anyway I fixed it this way:
Scanner scanner = new Scanner(System.in);
String token = scanner.nextLine();
Scanner scannerToken = new Scanner(token);
while (scannerToken.hasNext()) {
String statement = scannerToken.next();
if (statement.equals("("))
else if (statement.equals(")"))
else {
}
}

How do I make sure User input integer type only and integer that is greater than 0?

I am attempting to make sure the user input int type only and make sure the integer inputted is greater than 0.
I was able to come up with the following to make sure the input is int type:
Scanner scan = new Scanner(System.in);
while(!scanner.hasNextInt())
{
scanner.next();
}
int input = scan.nextInt();
But how should I include a condition checking to make sure the integer is greater than 0 as well?
The problem with your current approach is you've already ready the value from the Scanner before it reaches int input = scan.nextInt();, meaning that by the time you use nextInt, there's nothing in the Scanner to be read and it will wait for the next input from user...
Instead, you could read the String from the Scanner using next, use Integer.parseInt to try and parse the result to an int and then check the result, for example...
Scanner scanner = new Scanner(System.in);
int intValue = -1;
do {
System.out.print("Please enter a integer value greater than 0: ");
String next = scanner.next();
try {
intValue = Integer.parseInt(next);
} catch (NumberFormatException exp) {
}
} while (intValue < 0);
System.out.println("You input " + intValue);
put an if statement inside your while loop like this
if(num <= 0){
System.out.println("Enter a number greater than zero");
}
else{
break;
}
You may use a condition in your code but not in the loop as.
`
Scanner scan = new Scanner(System.in);
abc:
while(!scanner.hasNextInt())
{
scanner.next();
}
int input = scan.nextInt();
if(input <= 0){
goto abc;
}
`
using .isDigit() method then checking to see if that number is greater than 0 if it is a digit

Categories

Resources