I want it allow the user to enter in two int after the incorrect input. I tried continue; in the catch block, but it only threw run-time errors. I just want it to go back to the top of the main method after the throwing the error. See how in the pic it didn't allow the user to input any numbers. I want to fix that part.
Here's the code. This is only for practice.
/**
practing exceptions, example 1 in book for exceptions
*/
import java.util.Scanner;
public class PracticeExceptions extends Exception {
public static void main(String[] args)
{
String response = "y";
Scanner keyboard = new Scanner(System.in);
do{
int n1, n2;
double r;
System.out.println("Please enter two numbers");
try{
n1 = keyboard.nextInt();
n2 = keyboard.nextInt();
r = (double) n1/n2;
System.out.format("Your answer: %.2f %n", r);
}catch(Exception a){
System.out.println("Invaild input please try again");
}
System.out.println("Again (y/n)");
response = keyboard.next();
}while(response.equalsIgnoreCase("y"));
}
}
Get rid of the invalid input in you scanner buffer
}catch(Exception a){
System.out.println("Invalid input please try again");
keyboard.next();
}
The code will now drop down to System.out.println("Again (y/n)");
If you want to loop back to the top add a continue after keyboard.next();
Related
I want the program to not crash when the user inputs anything other than a number. For example, if someone enters random letters, it should display a message saying, "input not valid, please enter a valid integer". Then prompting them if they would want to continue or not.
public static void main(String[] args) throws IOException {
BufferedWriter out = new BufferedWriter(new FileWriter("outDataFile.txt"));
Scanner input=new Scanner(System.in);
int choice = 0;
String repeat;
//Loop repeats program until user quits
do
{
//Loop repeats until a valid input is found
do
{
//Asks for number and reads value
System.out.print("\nEnter an integer and press <Enter> ");
choice = input.nextInt();
//Prints error if invalid number
if(choice <= 0)
System.out.println("Invalid Input.");
There are multiple ways to achieve that:
First is to catch the exception thrown by the Scanner and flag the loop to carry on when an exception is caught. This is not a good practise since the exception thrown by the Scanner, InputMismatchException, is an unchecked exception. Meaning the cause of this exception can be easily caught by an if/else statement.
In your case, you should try to receive the input as a String, then validate the input if it looks like a number:
Loop per character approach:
String string = scanner.nextLine();
for (int i = 0; i < string; i++) {
char ch = string.charAt(i);
if (!Character.isDigit(ch)) {
System.out.println("Input is not a number");
break; // stop the for-loop
}
}
int input = Integer.parseInt(string);
RegEx approach:
String numericRegex = "[0-9]+";
String string = scanner.nextLine();
if (!string.matches(numericRegex)) {
System.out.println("Input is not a number");
}
int input = Integer.parseInt(string);
These are popular approach to your problem, it is now up to you on how will you control your loops to repeat when an invalid input is encountered.
Use a simple try catch that will catch and a simple recursive method as such:
import java.util.InputMismatchException;
import java.util.Scanner;
public class Test
{
public static void main(String[] args)
{
System.out.println(getUserInput());
}
private static int getUserInput()
{
int choice = 0;
Scanner input = new Scanner(System.in);
System.out.println("Enter a value");
try
{
choice = input.nextInt();
} catch (InputMismatchException exception)
{
System.out.println("Invalid input. Please enter a numeric value");
getUserInput();
}
return choice;
}
}
so I'm kind of new to catching errors and such. Anyways, the program is supposed to ask the user for 2 integers and then add them together. Simple, but if either of the numbers are not integers, than an error is thrown. Currently, if I enter 2 integers, instead of adding them, it just restarts the getAnswer() method and outputs them again. Also, if you enter more than one error, it will simply exit.
package javaapplication1;
import java.util.InputMismatchException;
import java.util.Scanner;
public class JavaApplication1 {
public static void main(String[] args) {
Intro();
System.out.println("Your answer: "+getAnswer());
}
private static void Intro() {
System.out.println("Hello this program adds 2 integers together and catches errors.");
getAnswer();
}
private static int getAnswer() throws InputMismatchException {
Scanner scanner = new Scanner(System.in);
try {
System.out.println("Please input a number");
int num1 = scanner.nextInt();
System.out.println("Please input a second number");
int num2 = scanner.nextInt();
return num1+ num2;
} catch (InputMismatchException exp) {
System.out.println("Exception thrown");
return 0;
}
}
}
You are calling getAnswer(); totally two times, so you just remove the call from Intro() method which will solve the problem.
private static void Intro() {
System.out.println("Hello this program adds 2
integers together and catches errors.");
}
If you want to prompt the user to reenter the input again, you can call the getAnswer() in the catch block as shown below:
private static int getAnswer() {
Scanner scanner = new Scanner(System.in);
try {
System.out.println("Please input a number");
int num1 = scanner.nextInt();
System.out.println("Please input a second number");
int num2 = scanner.nextInt();
return num1+ num2;
} catch (InputMismatchException exp) {
System.out.println("Exception thrown, please reenter values:");
getAnswer();
}
return 0;
}
One more point is that rather than catching the InputMismatchException, the other better way is read the inputs as strings and validate that they contain only numeric values like below:
private static int getAnswer() {
Scanner scanner = new Scanner(System.in);
System.out.println("Please input a number");
String num1 = scanner.nextLine();
System.out.println("Please input a second number");
String num2 = scanner.nextLine();
if(num1.matches("[0-9]+") && num2.matches("[0-9]+")) {
return Integer.parseInt(num1)+ Integer.parseInt(num2);
} else {
System.out.println(" Your inputs contain Invalid characters");
getAnswer();
}
return 0;
}
I'm writing a program that uses the Scanner class and want to use a try-catch block to catch InputMismatchExceptions. This is what I have written:
public class StudentInfo{
public static void main(String[] args){
Scanner scnr = new Scanner(System.in);
int creditHours = 0;
try
{
System.out.println("Please enter the number of credit hours that you currently have (do not count credit hours from classes that you are currently attending this semester)");
creditHours = scnr.nextInt();
}
catch(InputMismatchException e){
System.out.println("CLASSIFICATION ERROR: NUMBER NOT RECOGNIZED. ENTER AN INTEGER FOR CREDIT HOURS");
Scanner input = new Scanner(System.in);
creditHours = input.nextInt();
}
String studentClass = checkStudent (creditHours);
System.out.println("Official Student Classification: " + studentClass);
}
The try-catch block works one time around as in, if I put in 24.5 for example the first time around, it catches the exception and has the user retype the number of credit hours they have but if they retype a non-integer a second time, it fails to catch the error again and send out the appropriate message. So essentially, I was wondering if there was any way that it could keep catching the exception and sending out the error message no matter how many times they try it. I've tried using a do-while loop or a while statement but it doesn't work so yeah. Also, I created a new scanner variable in the catch block because if not, it doesn't allow me to input a new integer after giving the error message for some reason. It literally will throw the error that I typed and then proceed to give me Java's InputMismatchException error.
Here is my attempts at using a while loop:
int creditHours = 0;
while(creditHours <= 0){
try
{
System.out.println("Please enter the number of credit hours that you currently have (do not count credit hours from classes that you are currently attending this semester)");
creditHours = scnr.nextInt();
}
catch(InputMismatchException e){
System.out.println("CLASSIFICATION ERROR: NUMBER NOT RECOGNIZED. ENTER AN INTEGER FOR CREDIT HOURS");
Scanner input = new Scanner(System.in);
creditHours = input.nextInt();
}
}
String studentClass = checkStudent (creditHours);
System.out.println("Official Student Classification: " + studentClass);
}
you need the try-catch to be in a loop in order to re-run your code.
try this:
public class StudentInfo{
public static void main(String[] args){
int creditHours = 0;
boolean ok = false;
System.out.println("Please enter the number of credit hours that you currently have (do not count credit hours from classes that you are currently attending this semester)");
while (!ok)
{
try
{
Scanner scnr = new Scanner(System.in);
creditHours = scnr.nextInt();
ok = true;
}
catch(InputMismatchException e){
System.out.println("CLASSIFICATION ERROR: NUMBER NOT RECOGNIZED. ENTER AN INTEGER FOR CREDIT HOURS");
}
}
String studentClass = checkStudent (creditHours);
System.out.println("Official Student Classification: " + studentClass);
}
boolean loop = false;
double numberOfStudents;
System.out.print("Enter a number: ");
if ((scnr.nextLine().trim().isEmpty()) ) {
loop = true;
}
while (loop) {
System.out.println("Enter a number");
if (scnr.hasNextDouble() ){
System.out.println("Loop has stopped");
numberOfStudents = scnr.nextDouble();
loop = false;
}
}
System.out.println("You're outside the loop!");
I'm trying to get the program to say "Enter a number" until the user has entered an actual number (no white spaces or letters or signs). When the user has entered a number, it sets numberOfStudents equal to that number and breaks out of the loop.
But if you hit enter twice, it doesn't iterate. It only displays "Enter a number" once.
What is wrong with the loop logic? Why isn't it looping until valid input is taken?
For the actual answer to your question of "Why doesn't 'Enter a number' display more than once?" see Tom's comment (update: Tom's answer).
I've rewritten your loop in a way which preserves your code, but also makes it a little easier to handle format exceptions (though at the risk of silently swallowing an exception -- should be acceptable for this use case).
Can be up to you to use this design, here is an SO post on why empty catch blocks can be a bad practice.
public static void main(String args[])
{
boolean loop = true;
double numberOfStudents;
Scanner scnr = new Scanner(System.in);
while(loop){
System.out.print("Enter a number: ");
String input = scnr.nextLine();
try{
numberOfStudents = Double.parseDouble(input);
loop = false;
}catch(NumberFormatException e){
}
}
System.out.println("You're outside the loop!");
}
Output:
Enter a number:
Enter a number:
Enter a number:
Enter a number: 50
You're outside the loop!
First of all: Since you're reading from System.in a call to the input stream will block until the user entered a valid token.
So let's check first scan using your scnr variable:
scnr.nextLine()
nextLine() reads everything til the next line delimiter. So if you just press return, then it will successfully read it and will perform the next stuff.
The next call is:
scnr.hasNextDouble()
This call expects a "real" token and ignores white spaces, except as a delimiter between tokens. So if you just press return again it doesn't actually read that input. So it still waits for more (for the first token). That is why it stucks in your loop and you won't get another "Enter a number" output.
You can fix that by either enter a real token, like a number, or by changing the loop like trobbins said.
I hope you now understand your program flow a bit more :).
While trobbins code basically solves your problem, it's bad practice to use exceptions for flow control.
I used a small regexp to check if the value is a number. But this example is not complete, it will still crash it the user enters for example two decimal points. So you would need to create a proper number check or just use integers where the check is much easier.
Someone in the comments pointed out that people may want to enter scientific notation like 5e10, so this would also be another case to check for. If this is just some code you need as a proof of concept or something quick and dirty, you can go with the exception handling method but in production code you should avoid using exceptions this way.
double numberOfStudents;
Scanner scnr = new Scanner(System.in);
while(true) {
System.out.print("Enter a number: ");
String input = scnr.nextLine().trim();
if(input.matches("^[0-9\\.]{1,}$")) {
System.out.println("Loop has stopped");
numberOfStudents = Double.parseDouble(input);
break;
}
}
System.out.println("You're outside the loop!");
The following code should help you:
double numberOfStudents = 0;
Scanner scnr = new Scanner(System.in);
boolean readValue = false; //Check if the valid input is received
boolean shouldAskForNumber = true; //Need to ask for number again? Case for Enter
do {
if (shouldAskForNumber) {
System.out.print("Enter a number:");
shouldAskForNumber = false;
}
if (scnr.hasNextDouble()) {
numberOfStudents = scnr.nextDouble();
readValue = true;
} else {
String token = scnr.next();
if (!"".equals(token.trim())) { //Check for Enter or space
shouldAskForNumber = true;
}
}
} while (!readValue);
System.out.printf("Value read is %.0f\n", numberOfStudents);
System.out.println("You're outside the loop!");
Update
Understood the following statement in question different way:
But if you hit enter twice, it doesn't loop back. It only displays
"Enter a number" once.
The code is set to print "Enter a number" only once if the user hits RETURN/ENTER or enters space character. You may remove the special check and use the code if needed.
import java.util.Scanner;
public class Testing {
public static boolean checkInt(String s)
{
try
{
Integer.parseInt(s);
return true;
} catch (NumberFormatException ex)
{
return false;
}
}
public static void main(String[] args) {
boolean loop = false;
double numberOfStudents;
Scanner scnr = new Scanner(System.in);
String input = "";
while (!(checkInt(input))) {
System.out.println("Enter a number");
input = scnr.nextLine();
}
numberOfStudents = Integer.parseInt(input);
System.out.println("Number of students: " + numberOfStudents );
}
}
//this code is working fine, if you want you check it out.
//In your code your taking another input if the first is an int/double; if the first input is not a number then you have mentioned to take input again..
Use a debugger to see what the code is actually doing. Here's a guide on debugging in Eclipse. After you have finished debugging your code, you will probably know what the problem is.
Below code will help you
boolean loop = true;
double numberOfStudents;
Scanner scnr = new Scanner(System.in);
System.out.print("Enter a number: ");
String input = scnr.nextLine();
while(!scnr.hasNextDouble()){
System.out.print("Enter a number: ");
try{
numberOfStudents = Double.parseDouble(input);
break;
}catch(NumberFormatException e){
}
input = scnr.nextLine();
}
System.out.println("You're outside the loop!");
The following code is working,
boolean loop = true;
double numberOfStudents;
Scanner scnr=new Scanner(System.in);
while(loop) {
System.out.println("Enter a number");
if ((scnr.nextLine().trim().isEmpty()) ) {
loop = true;
}
if (scnr.hasNextDouble() ){
System.out.println("Loop has stopped");
numberOfStudents = scnr.nextDouble();
loop = false;
}
}
System.out.println("You're outside the loop!");
The output is,
run:
Enter a number
hj
po
Enter a number
lhf
Enter a number
o
Enter a number
p
Enter a number
a
Enter a number
34
Loop has stopped
You're outside the loop!
You have to scan the next line if you want to get more values form the scanner again. The code should be like:
while (loop) {
System.out.println("Enter a number");
if(!(scnr.nextLine().trim().isEmpty())){
if (scnr.hasNextDouble() ){
System.out.println("Loop has stopped");
numberOfStudents = scnr.nextDouble();
loop = false;
}
}
}
I am having trouble with entering non-integers into an integer field. I am only taking precautions so that if another person uses/works on my program they don't get this InputMismatchException.
When I enter a non-digit character into the input variable, I get the above error. Is there any way to compensate for this like one could do for a NullPointerException when it comes to strings?
This code is redacted just to include the relevant portions causing the problem.
import java.util.Scanner;
class MyWorld {
public static void main(String[] args) {
Scanner user_input = new Scanner(System.in);
int input = 0;
System.out.println("What is your age? : ");
input = user_input.nextInt();
System.out.println("You are: " +input+ " years old");
}
}
You can use an if statement to check if user_input hasNextInt(). If the input is an integer, then set input equal to user_input.nextInt(). Otherwise, display a message stating that the input is invalid. This should prevent exceptions.
System.out.println("What is your age? : ");
if(user_input.hasNextInt()) {
input = user_input.nextInt();
}
else {
System.out.println("That is not an integer.");
}
Here is some more information about hasNextInt() from Javadocs.
On a side note, variable names in Java should follow the lowerMixedCase convention. For example, user_input should be changed to userInput.
You can add a try-catch block:
import java.util.Scanner;
class MyWorld {
public static void main(String[] args) {
Scanner user_input = new Scanner(System.in);
int input = 0;
System.out.println("What is your age? : ");
try{
input = user_input.nextInt();
}catch(InputMisMatchException ex)
System.out.println("An error ocurred");
}
System.out.println("You are: " +input+ " years old");
}
}
If you want to provide the user to enter another int you can create a boolean variable and make a do-while loop to repeat it. As follows:
boolean end = false;
//code
do
{
try{
input = user_input.nextInt();
end = true;
}catch(InputMisMatchException ex)
System.out.println("An error ocurred");
end = false;
System.out.println("Try again");
input.nextLine();
}
}while(end == false);
This is a try-catch block. You need to use this if you want to be sure of not making the program-flow stop.
try {
input = user_input.nextInt();
}
catch (InputMismatchException exception) { //here you can catch that exception, so program will not stop
System.out.println("Integers only, please."); //this is a comment
scanner.nextLine(); //gives a possibility to try giving an input again
}
Test using hasNextInt().
Scanner user_input = new Scanner(System.in);
System.out.println("What is your age?");
if (user_input.hasNextInt()) {
int input = user_input.nextInt();
System.out.println("You are " + input + " years old");
} else {
System.out.println("You are a baby");
}
Use Scanner's next() method to get data instead of using nextInt(). Then parse it to integer using int input = Integer.parseInt(inputString);
parseInt() method throws NumberFormatException if it is not int, which you can handle accordingly.