i wrote this code to control input so user cannot enter anything except integers
but problem is that: when an Exception occures, the message in Exception block is continousely printed and never ends, what i can do ?
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int i=0;
boolean success = false;
System.out.println("Enter an int numbers :");
while(!success) {//"while loop" will continue until user enters an integer
try {
i = scanner.nextInt();
success=true;//if user entered an integer "while loop" will end, or if user entered another type Exception will occur
}catch(InputMismatchException e) {
System.out.println(" enter only integers ");
}
}
System.out.println(i);
}
you should add scanner.nextLine(); in your catch block
the explenation is that you need to clear the scanner and to do so you should use nextLine()
"
To clear the Scanner and to use it again without destroying it, we can use the nextLine() method of the Scanner class, which scans the current line and then sets the Scanner to the next line to perform any other operations on the new line."
for more understanding visits the link
your code will look like this
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int i=0;
boolean success = false;
System.out.println("Enter an int numbers :");
while(!success) {//"while loop" will continue until user enters an integer
try {
i = scanner.nextInt();
success=true;//if user entered an integer "while loop" will end, or if user entered another type Exception will occur
}catch(InputMismatchException e) {
System.out.println(" enter only integers ");
scanner.nextLine();
}
}
System.out.println(i);
}
Add scanner.nextLine(); in your try and catch block. Like this
while(!success) {//"while loop" will continue until user enters an integer
try {
i = scanner.nextInt();
success=true;//if user entered an integer "while loop" will end, or if user entered another type Exception will occur
scanner.nextLine();
}catch(InputMismatchException e) {
System.out.println(" enter only integers ");
scanner.nextLine();
}
}
You can also add just one scanner.nextLine() in the finaly block, which should be below catch
Related
I wrote a program that accepts numbers from the user, and if the user entered, for example, a string instead of a number, then I recursively call the function for the user to enter a number, but in my example, the program throws a StackOverflowException error. If you know what the problem is, please write.
Code:
private static void inputMethod() {
try {
System.err.print("Enter a range from ");
c = input.nextInt();
System.err.print("Enter a range to ");
d = input.nextInt();
if(c > d) {
System.err.println("Invalid Range Entry");
inputMethod();
return;
}
System.err.print("Enter the sum of digits ");
q = input.nextInt();
findNaturalNumbers();
} catch(InputMismatchException e) {
inputMethod();
}
}
The problem is that when InputMismatchExcpetion is thrown, the garbage input that caused the error is still waiting to be read again by the next scanner call. That's so you could potentially go back and try to read it again with next() or nextLine().
The cure is to "flush the toilet", so to speak, by calling either next() or nextLine() in your InputMismatchException handler:
boolean inputWasGood = false;
while (!inputWasGood){
try {
System.out.println("Enter a number: ");
c = input.nextInt();
inputWasGood = true;
} catch (InputMismatchException ex) {
input.nextLine(); // FLUSH AWAY THE GARBAGE!!
System.out.println("Please don't enter garbage!");
}
}
// FINALLY! We got some good input...
If you enter a letter instead of a number the input.nextInt() method throws an exception, but the cursor position in the input stream scanner is not advanced, it's still pointing to the letter. In the exception handler you call inputMethod() again, and because the cursor position is the same the input.nextInt() will again throw an exception, which will cause another call of inputMethod() and so on until the stack is blown up. What you should do is to use a hasNextInt() method to check if the next token on the stream is a correctly formatted integer and if so - read it with nextInt(). To simplify the process you can try to create an additional method which will prompt the user and ask for the input until the correct input is provided:
private int readInt(Scanner scanner, String prompt) {
while (true) {
System.out.println(prompt);
if (scanner.hasNextInt()) {
return scanner.nextInt();
}
System.out.println("Incorrect format of an integer number");
scanner.nextLine();
}
}
and then you can use it like this:
do {
c = readInt(input, "Enter a range from ");
d = readInt(input, "Enter a range to ");
if(c > d) {
System.err.println("Invalid Range Entry");
}
} while (c > d);
q = readInt(input, "Enter the sum of digits ");
findNaturalNumbers();
For a college assessment I'm having to use a Scanner called sc with a class-level scope, and the entirety of the program has to be contained in a single class. The main method calls a menu() method, which uses the Scanner and a for loop to call one of two methods in response to user input.
One of the two methods uses the Scanner to calculate the factorial of an input integer. Once the method is executed, the for loop in menu() continues. To avoid an InputMismatchException due to the user entering a float, I used try/catch. However when the program returns back to the menu() for loop the Scanner causes an InputMismatchException when assigning to choice. How can I get Scanner to prompt the user for input again? Apologies if I'm missing something obvious, this is the first programming language I've ever learned. This should be the stripped down compilable code:
package summativeassessment;
import java.util.InputMismatchException;
import java.util.Scanner;
public class SummativeAssessment {
private static Scanner sc = new Scanner(System.in);
public static void main(String[] args) {
menu();
}
public static void menu(){
String fName;
String sName;
System.out.print("Enter your first name: ");
fName = sc.next();
System.out.print("Enter your last name: ");
sName = sc.next();
try{
for(int choice = 1; choice!=0;){
System.out.print("Option 1 to generate username. Option 2 to calculate factorial. Press 0 to quit: ");
choice = sc.nextInt();
switch(choice){
case 2:
System.out.println(fName+" "+sName+", you have selected option 2");
numberFactorial();
break;
case 0:
break;
default:
System.out.println("Invalid option. Please try again.");
}
}
} catch(InputMismatchException ex){
String msg = ex.getMessage();
System.out.println(msg);
}
}
public static void numberFactorial(){
System.out.print("Enter a number: ");
try{
int numIn = sc.nextInt();
long result = numIn;
if(numIn>0){
for(int factor = 1; factor<numIn; factor++){
result *= factor;
if(factor==numIn-1){
System.out.println("The factorial is "+result);
}
}
}
else{
System.out.println("Enter a positive integer greater than 0");
}
}
catch(InputMismatchException ex){
System.out.println("Input invalid");
}
}
}
I debugged your code and got this result:
If you enter a float as input you trigger the InputMismatchException but there is still something in your buffer. So the next time sc.nextInt() is called, it won't wait until you input a value because something is in the buffer already, so it takes the next value out of the buffer and tries to interpret is as an integer. However, it fails to do so, because it is not an integer, so an InputMismatchException is raised again and caught in your menu's catch, now leading to the exit of the program.
The solution is to draw whatever is left in the buffer after the exception was raised the first time.
So the working code will contain a buffer clearing sc.next() inside the exception:
public static void numberFactorial(){
System.out.print("Enter a number: ");
try{
int numIn = sc.nextInt();
long result = numIn;
if(numIn>0){
for(int factor = 1; factor<numIn; factor++){
result *= factor;
if(factor==numIn-1){
System.out.println("The factorial is "+result);
}
}
}
else{
System.out.println("Enter a positive integer greater than 0");
}
}
catch(InputMismatchException ex){
System.out.println("Input invalid");
sc.next();
}
}
While using the nextInt() method of Scanner class, if InputMismatchException is being thrown, shall I handle that by catch block ?
It's a runtime exception, but caused by user input and not programmer's mistake.
Here is my code.
package com.sample.programs;
import java.util.InputMismatchException;
import java.util.Scanner;
public class ScannerPractice {
public static void main(String[] args) {
readInteger();
}
private static void readInteger() {
// Created a Scanner object
Scanner input = new Scanner(System.in);
// Display a prompt text
System.out.println("Please enter an integer");
// Accept the input from user
int number;
try {
number = input.nextInt();
// Display the output to user
System.out.println("You entered: " + number);
} catch (InputMismatchException exception) {
System.err.println("You have entered wrong input. Please enter a number");
// Log the stack trace
readInteger();
} finally {
input.close();
}
}
}
Yes. Is better to handle the user wrong input beacouse you cannot control or be sure that the user will aligned data correctly, and you cannot read doubles, or strings with readInteger().
So I will handle the exception.
Regards.
No, you should call hasNextInt() before calling nextInt().
The exception truly means programmer error, since the programmer forgot to check validity before calling the method.
If you then want to prompt the user again, remember to discard the bad input first.
Scanner input = new Scanner(System.in);
int value;
for (;;) {
System.out.println("Enter number between 1 and 10:");
if (! input.hasNextInt()) {
System.out.println("** Not a number");
input.nextLine(); // discard bad input
continue; // prompt again
}
value = input.nextInt();
if (value < 1 || value > 10) {
System.out.println("** Number must be between 1 and 10");
input.nextLine(); // discard any bad input following number
continue; // prompt again
}
if (! input.nextLine().trim().isEmpty()) {
System.out.println("** Bad input found after number");
continue; // prompt again
}
break; // we got good value
}
// use value here
// don't close input
I want to validate user input using the exception handling mechanism.
For example, let's say that I ask the user to enter integer input and they enter a character. In that case, I'd like to tell them that they entered the incorrect input, and in addition to that, I want them to prompt them to read in an integer again, and keep doing that until they enter an acceptable input.
I have seen some similar questions, but they do not take in the user's input again, they just print out that the input is incorrect.
Using do-while, I'd do something like this:
Scanner reader = new Scanner(System.in);
System.out.println("Please enter an integer: ");
int i = 0;
do {
i = reader.nextInt();
} while ( ((Object) i).getClass().getName() != Integer ) {
System.out.println("You did not enter an int. Please enter an integer: ");
}
System.out.println("Input of type int: " + i);
PROBLEMS:
An InputMismatchException will be raised on the 5th line, before the statement checking the while condition is reached.
I do want to learn to do input validation using the exception handling idioms.
So when the user enters a wrong input, how do I (1) tell them that their input is incorrect and (2) read in their input again (and keep doing that until they enter a correct input), using the try-catch mechanism?
EDIT: #Italhouarne
import java.util.InputMismatchException;
import java.util.Scanner;
public class WhyThisInfiniteLoop {
public static void main (String [] args) {
Scanner reader = new Scanner(System.in);
int i = 0;
System.out.println("Please enter an integer: ");
while(true){
try{
i = reader.nextInt();
break;
}catch(InputMismatchException ex){
System.out.println("You did not enter an int. Please enter an integer:");
}
}
System.out.println("Input of type int: " + i);
}
}
In Java, it is best to use try/catch for only "exceptional" circumstances. I would use the Scanner class to detect if an int or some other invalid character is entered.
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
boolean gotInt = false;
while (!gotInt) {
System.out.print("Enter int: ");
if (scan.hasNextInt()){
gotInt = true;
}
else {
scan.next(); //clear current input
System.out.println("Not an integer");
}
}
int theInt = scan.nextInt();
}
}
Here you go :
Scanner sc = new Scanner(System.in);
boolean validInput = false;
int value;
do{
System.out.println("Please enter an integer");
try{
value = Integer.parseInt(sc.nextLine());
validInput = true;
}catch(IllegalArgumentException e){
System.out.println("Invalid value");
}
}while(!validInput);
You can try the following:
Scanner reader = new Scanner(System.in);
System.out.println("Please enter an integer: ");
int i = 0;
while(true){
try{
i = reader.nextInt();
break;
}catch(InputMismatchException ex){
System.out.println("You did not enter an int. Please enter an integer:");
}
}
System.out.println("Input of type int: " + i);
The code below asks the user how many racers he/she would like.
while (true) { // loops forever until break
try { // checks code for exceptions
System.out.println("How many racers should" + " participate in the race?");
amountRacers = in.nextInt();
break; // if no exceptions breaks out of loop
}
catch (InputMismatchException e) { // if an exception appears prints message below
System.err.println("Please enter a number! " + e.getMessage());
continue; // continues to loop if exception is found
}
}
If a number is entered at amoutnRacers = in.nextInt(); the code breaks out of the loop and the rest of the program runs fine; however, when I enter something such as "awredsf" it should catch that exception, which it does. Instead of prompting the user again it loops continuously, which to me does not make sense.
The program prints like this when looping continuously:
How many racers should participate in the race?
How many racers should participate in the race?
How many racers should participate in the race?
How many racers should participate in the race?
How many racers should participate in the race?
How many racers should participate in the race?
How many racers should participate in the race?Please enter a number! null
Please enter a number! null
Please enter a number! null
Please enter a number! null
Please enter a number! null
Please enter a number! null
Please enter a number! null
...
I do not understand what is going on amountRacers = in.nextInt(); so why is the user not able to enter a number?
Just add input.next() once you catch InputMismatchException.
catch (InputMismatchException e) { //if an exception appears prints message below
System.err.println("Please enter a number! " + e.getMessage());
input.next(); // clear scanner wrong input
continue; // continues to loop if exception is found
}
You need to clear the wrong input, which scanner automatically does not.
Today i solved this problem :-) This is my code. I think that i help
public int choice () throws Exception{
Scanner read = new Scanner(System.in));
System.out.println("Choose the option from the upper list");
int auxiliaryChoiceMenu = 5;
int auxiliaryVariable = -1;
boolean auxiliaryBoolean = false;
while (!auxiliaryBoolean) {
try {
auxiliaryVariable = read.nextInt();
read.nextLine();
} catch (Exception e) {
System.out.println("incorrect data, try again"+e);
read.nextLine();
continue;
}
if (auxiliaryVariable<0 || auxiliaryVariable>auxiliaryChoiceMenu){
System.out.println("incorrect data, try again");
} else {
auxiliaryBoolean = true;
}
choiceMenu = auxiliaryVariable;
}
return choiceMenu;
//choicemenu is a external variable
}
You may need to create a Scanner class for getting standard input streamed from the keyboard. You should have a statement somewhere in your code that creates an instance of a Scanner class like: Scanner in = new Scanner(System.in);
so the " in " variable in your statement: amountRacers = in.nextInt(); waits and scans for entered input from the keyboard and stores it.
Why use a loop with a try and catch?
My advice would be to always use a try and catch with either a while or do while loop, so you can ask the user to repeat his/her input. It also depends which loop you already use and/or on how your code is structured.
For example if you already have a do while loop then I would advice you to simply adjust/modify your existing loop.
I will post some examples on how you can use a try and catch with a loop to repeat the input after a user has provided a wrong one.
See examples below:
Example 1
Scanner input = new Scanner(System.in);
int exampleInput = 0;
do {
try {
System.out.print("\nEnter an integer from 1 to 25: ");
exampleInput = input.nextInt();
}
catch (InputMismatchException e) { //if an exception appears prints message below
System.err.println("Wrong input! Enter an integer from 1 to 25");
input.next(); // Clear scanner buffer of wrong input
}
} while (exampleInput < 1 || exampleInput > 25);
System.out.println("Print exampleInput: " + exampleInput);
Example 2
Scanner input = new Scanner(System.in);
int exampleInput; // Here you don't need to initialize this variable because you don't need it as a condition for the loop.
boolean isDone = false;
do {
try {
System.out.print("\nEnter an integer: ");
exampleInput = input.nextInt();
isDone = true;
}
catch (InputMismatchException e) { //if an exception appears prints message below
System.err.println("Wrong input! Enter an integer");
input.next(); // Clear scanner buffer of wrong input
}
} while (!isDone);
System.out.println("Print exampleInput: " + exampleInput);
Example 3
Scanner input = new Scanner(System.in);
int exampleInput; // Here you don't need to initialize this variable because you don't need it as a condition for the loop.
boolean isDoneLoop2 = false;
while (!isDoneLoop2) {
try {
System.out.print("\nEnter an integer: ");
exampleInput = input.nextInt();
isDoneLoop2 = true;
}
catch (InputMismatchException e) { //if an exception appears prints message below
System.err.println("Wrong input! Enter an integer");
input.next(); // Clear scanner buffer of wrong input
}
}
System.out.println("Print exampleInput: " + exampleInput);
This works for me.
while (true) {
try {
System.out.print("Ingrese la cantidad de puestos de atenciĆ³n: ");
int puestos = Integer.parseInt(scn.nextLine());
break;
}
catch (NumberFormatException e) {
System.out.println("Ingrese un valor correcto");
scn.reset();
continue;
}
}