Looping do...while uncertainty - java

In the catch block, I'm trying to correct for user bad-input issues. When testing it, if I use the "break" keyword, it doesn't jump to the initial question. If I use "continue", it loops infinitely. "Sc.next();" doesn't seem to resolve it either.
Here's the relevant part of the code.
public class ComputerAge {
private static int age;
private static int year;
private static int month;
private static int date;
private static Calendar birthdate;
static Scanner sc = new Scanner(System.in);
public static void main(String[] args) {
System.out.print("Enter the numeral representing your birth month: ");
do {
try {
month = sc.nextInt();
} catch (InputMismatchException ime){
System.out.println("Your respone must be a whole number");
break;
}
} while (!sc.hasNextInt());

In order to fix the problem, we should identify what we want to accomplish at the end.
We want the month to be a numeral month, that is number > 0.
Thus:
If a user fill a correct number month will be filled.
Otherwise, Exception will be thrown and month will stay as '0'.
Conclusion: We want our program will keep running when month is equals 0.
The solution is pretty simple:
While condition should be:
while (month == 0);
And you should change break to sc.next().

The problem with your approach is that when you call sc.nextInt() and it throws an exception, Scanner does not advance its reading position. You need to advance the reading pointer by calling sc.next() inside the catch block instead of the break:
do {
try {
month = sc.nextInt();
} catch (InputMismatchException ime){
System.out.println("Your respone must be a whole number");
sc.next(); // This will advance the reading position
}
} while (!sc.hasNextInt());

I think you should use an infinite loop, and when the input is correct (no exception thrown), use break to finish the loop:
public static void main(String args[])
{
System.out.print("Enter the numeral representing your birth month: ");
do {
try {
int month = sc.nextInt();
break;
} catch (InputMismatchException ime) {
System.out.println("Your respone must be a whole number");
sc.nextLine();
}
} while (true);
}
Also, you will have to use sc.nextLine() in the catch block because when you enter some input and press Enter, a new-line character is added, and nextInt() doesn't read it. You have to use nextLine() to consume that character. For further information about this issue you could read this.

First of all, you have to avoid use try/catch in iteratives sentences in order to improve perfomance.
You can recode for the break to work in this way (keep in mind that de do-while will execute at least one time, so if your scanner retrieve null value, you will have nullPointer)
try {
while (sc != null && !sc.hasNextInt()) {
month = sc.nextInt();
}
} catch (InputMismatchException ime){
System.out.println("Your respone must be a whole number");
}

Make sure you can get the integer first, and use regular expressions. Don't use exceptions if possible to enforce code logic.
int month;
boolean correct = false;
while (!correct && sc.hasNextLine())
{
String line = sc.nextLine();
if (!line.matches("^[0-9]+$"))
{
System.out.println("Your response must be a whole number");
correct = false;
}
else
{
month = Integer.parseInt(line);
correct = true;
}
}

Related

How can I validate user input in Java

I am currently experimenting with Java, trying to get the user to input an integer. If the user doesn't enter an integer I want a message to appear saying "You need to enter an Integer: " with a completely new input field to the original one.
Code:
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Scanner inputScanner = new Scanner(System.in);
int counter = 0;
boolean run = true;
int userInput = 0;
while (run) {
System.out.print("Enter an integer: ");
if (inputScanner.hasNextInt()) {
userInput = inputScanner.nextInt();
} else if (!inputScanner.hasNextInt()) {
while (!inputScanner.hasNextInt()) {
System.out.print("You need to enter an Integer: ");
userInput = inputScanner.nextInt();
}
}
System.out.println(userInput);
if (counter == 6) {
run = false;
}
counter++;
}
}
}
At the moment the code above gives an Exception error ("java.util.InputMismatchException"). I have tried to use a try/catch but this doesn't really work because I want the user to see the second message ("You need to enter an Integer") everytime they don't enter an integer and I don't want it to re-loop around the main run loop for the same reason. I'm sure there is a better way to do this, however I am not sure of it. Any help will be massively appreciated, thanks in advance.
In this case it would make more sense for the Scanner to use hasNextLine and then convert the String to an Integer. If that you could do something like this:
try {
new Integer(inputScanner.hasNextLine);
} catch (Exception e) {
System.out.println(“<error message>”)
}
In place of the if(inputScanner.hasNextInt()) due to the fact that the hasNextInt function will error out if there is not an Integer to be read.

Java Error when text input instead of number

I am just trying to get code to work where the code asks again for an answer, if text or a symbol is entered, instead of a required integer:
import java.util.Scanner;
class timecalc {
int hrs = 0;
int min = 0;
static int hourflag = 0;
static int minflag = 0;
Scanner sc = new Scanner(System.in);
public int getHours() {
try {
hourflag = hourflag + 1;
if (hourflag > 1) {
System.out.println("Invalid month Please enter hours again:");
}
System.out.println("Enter month:");
return hrs = sc.nextInt();
} catch (InputMisMAtchException e) {
System.out.println("entered invalid input " + e);
}
}
Have reviewed answers already given but cant get a workable solution
Any ideas?
I won't give you the entire code, but just a hint or psuedo-code. As an exercise you can implement it as per your requirement.
System.out.println("Enter month:");
while (true) {
try {
int min = sc.nextInt();
break;
} catch (InputMismatchException ex) {
System.err.println("Invalid input, please enter again");
sc.nextLine(); // <----- advance the scanner
}
}
Here the logic is to loop until we get the right input. If it is an invalid input, the loop never breaks.
Also as a side-note, I would recommend you to create just one method to fetch correct inputs and call it respectively from other methods. Rather than duplicating this logic everywhere.

Exception handling with a do-while loop in Java

The algorithm should take in 3 integers to an ArrayList. If the input is not an integer, then there should be a prompt. When I execute my code the catch clause is executed, but the program runs into a infinite loop. Could someone guide me into the right direction, I appreciate the help. :-D
package chapter_08;
import java.util.Scanner;
import java.util.List;
import java.util.ArrayList;
public class IntegerList {
static List<Integer> numbers = new ArrayList<Integer>();
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int counter = 1;
int inputNum;
do {
System.out.print("Type " + counter + " integer: " );
try {
inputNum = input.nextInt();
numbers.add(inputNum);
counter += 1;
}
catch (Exception exc) {
System.out.println("invalid number");
}
} while (!(numbers.size() == 3));
}
}
That is because when the next int is read using nextInt() and it fails, the Scanner still contains the typed contents. Then, when re-entering the do-while loop, input.nextInt() tries to parse it again with the same contents.
You need to 'flush' the Scanner contents with nextLine():
catch (Exception exc) {
input.nextLine();
System.out.println("invalid number");
}
Notes:
You can remove the counter variable, because you're not using it. Otherwise, you could replace counter += 1 by counter++.
You can replace while (!(numbers.size() == 3)) with while (numbers.size() != 3), or even better: while (numbers.size() < 3).
When catching exceptions, you should be as specific as possible, unless you have a very good reason to do otherwise. Exception should be replaced by InputMismatchException in your case.
If inputNum = input.nextInt(); cannot be fit into an int and a InputMismatchException is raised, the input of the Scanner is not consumed.
So after the catch, it loops and it goes again here :
inputNum = input.nextInt();
with exactly the same content in the input.
So you should execute input.nextLine(); in the catch statement to discard the current input and allow a new input from the user.
Besides it makes more sense to catch InputMismatchException rather than Exception as other exception with no relation with a mismatch could occur and it would not be useful to display to the user "invalid number " if it is not the issue :
catch (InputMismatchException e){
System.out.println("invalid number ");
input.nextLine();
}
You should to use a break; in your catch(){} like so :
try {
inputNum = input.nextInt();
numbers.add(inputNum);
counter += 1;
} catch (Exception e) {
System.out.println("invalid number ");
break;
}
So if one input is not correct break your loop.
try changing
inputNum = input.nextInt();
to
String inputText=input.next();
inputNum = Integer.valueOf(inputText);
it works perfectly well.
You need to move the scanner to the next line. Add this line of code below the error message in the catch section.
input.nextLine();

Variable scope in try catch block

I am creating a user interface via command line that will ask for options from 1 - 4 and I want error checking. Only an integer between 1 - 4 is allowed. This is the code I have so far. I want the method to return the userInput integer to another method that will do some stuff with it.
package contactmanager;
import java.util.InputMismatchException;
import java.util.Scanner;
/**
*
* #author andyjohnson
*/
public class UserInterface {
public static Integer GetInput() {
Scanner in = new Scanner(System.in);
//Integer userInput;
System.out.println("Welcome to the contact manager\nMake a selection below:");
System.out.println("1)Display Contacts\n2)Add new business contact\n3)Add new personal contact\n4)Quit");
try {
Integer userInput = in.nextInt();
if (userInput < 1 || userInput > 4) {
System.out.println("Please enter a valid selection");
UserInterface.GetInput();
}
} catch (InputMismatchException e) {
e.getMessage();
System.out.println("Please enter a valid selection");
UserInterface.GetInput();
}
return userInput;
}
}
My return statement is underlined in the IDE and is telling me it isn't initialized. I want to initialize it globally but allow the try statement to change the value. I've tried this.userInput = userInput but I can't figure out where my scope is broken. How do I give the try block global scope? I'm new to java, so anything is helpful. Thanks!
You can just declare userInput variable outside the try-catch block:
package contactmanager;
import java.util.InputMismatchException;
import java.util.Scanner;
public class UserInterface {
public static Integer GetInput() {
Scanner in = new Scanner(System.in);
System.out.println("Welcome to the contact manager\nMake a selection below:");
System.out.println("1)Display Contacts\n2)Add new business contact\n3)Add new personal contact\n4)Quit");
Integer userInput = null;
try {
userInput = in.nextInt();
if (userInput < 1 || userInput > 4) {
System.out.println("Please enter a valid selection");
UserInterface.GetInput();
}
} catch (InputMismatchException e) {
e.getMessage();
System.out.println("Please enter a valid selection");
UserInterface.GetInput();
}
return userInput;
}
}
The try-catch block has a scope that is dissimilar to just writing code in-line with the rest of the method.
I think the problem you are having is in this line where the variable userInput is first declared inside the try-catch block:
Integer userInput = in.nextInt();
The reason why this is an issue:
Consider if the try-catch block failed. What would then be returned? The variable userInput hasn't even been defined, so Java would have no idea what to return.
The fix is relatively simple. You want to just move it out of the try-catch block, like so. That should get rid of your return error. I noticed you commented this change out. Why?
But I have an additional suggestion. Why are you calling UserInterface.GetInput()? Why not have the method accept the parameter of the valid input and simply don't call it when the data is not formatted appropriately? Do you use it? This would take away the need of a truly global-scoped variable.
Because of how this method is written, it must return an Integer of some kind, unless you write it should that the method throws an exception that is caught somewhere downstream.
I tried to make some fixes I think would make the most sense:
Scanner in = new Scanner(System.in);
Integer userInput; // Integer representation of user input
try {
Integer a = in.nextInt(); // if a can be assigned to an Integer this line work
if (a < 1 || a > 4) {
// called if the input can be assigned to an Integer and is within the range
userInput = a;
}
} catch (InputMismatchException e) {
// otherwise the catch block is called
System.out.println("Please enter a valid selection");
}
return userInput;
Maybe you want to call UserInterface.GetInput() inside the range check? Hope this helps!
Edit: Using a sentinel flag instead of recalling the method
Scanner input = new Scanner(System.in);
System.out.println("Please enter a valid Integer. When done type DONE ");
// this method will keep cycling until the String DONE is typed
// you could make this condition whatever you want
while (!input.hasNext("DONE")) {
String a = input.next(); // gets the next item from the Scanner
try {
Integer b = Integer.parseInt(a); // tries to 'cast' the String to an Integer
if (b < 1 || b > 4) {
System.out.println("Input is valid!");
} else {
System.out.println("Input is invalid!");
}
} catch (NumberFormatException e) {
System.out.println("Please enter a valid selection!");
}
}

How can I use hasNextInt() to catch an exception? I need Int but if input is character, that is bad

I have been trying to stop the exceptions but I cannot figure out how.
I tried parseInt, java.util.NormalExceptionMismatch etc.
Does anyone have any insight how to fix this problem? Formatting is a bit off due to copy and paste.
do
{
System.out.print(
"How many integers shall we compare? (Enter a positive integer):");
select = intFind.nextInt();
if (!intFind.hasNextInt())
intFind.next();
{
// Display the following text in the event of an invalid input
System.out.println("Invalid input!");
}
}while(select < 0)
Other methods I have tried :
do
{
System.out.print(
"How many integers shall we compare? (Enter a positive integer):");
select = intFind.nextInt();
{
try{
select = intFind.nextInt();
}catch (java.util.InputMismatchException e)
{
// Display the following text in the event of an invalid input
System.out.println("Invalid input!");
return;
}
}
}while(select < 0)
It seems to me that you want to skip everything until you get an integer. This code here skips any input except an integer.
As long as there is no integer available (while (!in.hasNextInt())) discard the available input (in.next). When integer is available - read it (int num = in.nextInt();)
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (!in.hasNextInt()) {
in.next();
}
int num = in.nextInt();
System.out.println("Thank you for choosing " + num + " today.");
}
}
Quick sample of how to catch exceptions:
int exceptionSample()
{
int num = 0;
boolean done = false;
while(!done)
{
// prompt for input
// inputStr = read input
try {
num = Integer.parseInt(inputStr);
done = true;
}
catch(NumberFormatException ex) {
// Error msg
}
}
return num;
}
IMO, the best practice is to use nextLine() to get a String input, then parseInt it to get the integer. If unparsable, just complain back to the user and request re-entry.
Remember you may have to do a second nextLine() (discard the input) to clear up the buffer.

Categories