What possible exceptions are there if User enters String instead of Int? - java

I am just playing with Java.I'm trying to force my program to only accept number digits 1 and 2. I believe I have successfully done this using a while loop (please correct me if I'm wrong). But how do I go about printing an error statement if the user enters a string. eg: "abc".
My code:
while (response != 1 && response != 2) {
System.out.println("Please enter 1 for Car or 2 for Van: ");
response = scan.nextInt();
}
if (response == 1) {
vehicleType = VehicleType.CAR;
while (numPassengerSeats < 4 || numPassengerSeats > 7) {
System.out.println("Please enter the number of Passengers: ");
numPassengerSeats = scan.nextInt();
}
} else {
vehicleType = VehicleType.VAN;
while (true) {
System.out.println("Please enter the last maintenance date (dd/mm/yyyy): ");
String formattedDate = scan.next();
lastMaintenanceDate = formatDate(formattedDate);
if (lastMaintenanceDate != null)
break;
}
}

Let's have a look at javadoc for nextInt():
Scans the next token of the input as an int. An invocation of this
method of the form nextInt() behaves in exactly the same way as the
invocation nextInt(radix), where radix is the default radix of this
scanner.
Returns: the int scanned from the input
Throws:
InputMismatchException
- if the next token does not match the Integer regular expression, or is out of range
NoSuchElementException - if input is exhausted
IllegalStateException - if this scanner is closed
As per javadoc, it throws InputMismatchException if the user enters a String instead of an int. So, we need to handle it.

I think you have not successfully force your program to accept just integers since by using java.util.Scanner.nextInt(), user can still be able to input non integers, however java.util.Scanner.nextInt() will just throw an exception. Refer to this for possible exception thrown.
I have made a solution to force your program to accept just integers. Just follow the sample code below:
Sample code:
package main;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int response = 0;
Scanner scan = new Scanner(System.in);
while (response != 1 && response != 2) {
System.out.println("Please enter 1 for Car or 2 for Van: ");
try {
response = Integer.parseInt(scan.nextLine());
if (response != 1 && response != 2) {
System.out.println("Input is not in choices!");
}
} catch (NumberFormatException e) {
System.out.println("Input is invalid!");
}
}
scan.close();
}
}

Related

Why is my method making me enter input twice before reaching the next method?

I'm making a simple mortgage calculator and trying to validate two things through two "if-statements" before moving on to the next method. The first thing I'm checking is if the input from the scanner is an integer. If it is, I then want to check if the integer is between 1,000 and 1,000,000.
Below is the specific code:
public static Integer checkPrincipalValidation(Scanner scanner) {
while (true) {
if (scanner.hasNextInt()) {
principal = parseInt(scanner.nextLine());
if (principal >= 1_000 && principal <= 1_000_000) {
break;
}
System.out.println(scanner.nextLine() + " is not between 1,000 and 1,000,000. Please enter correct Principal (1K - $1M):");
}
if (!scanner.hasNextInt()) {
System.out.println(scanner.nextLine() + " is not a valid integer. Please enter correct Principal (Integer):");
}
}
return principal;
}
Below is the whole file if interested:
import java.util.Scanner;
import static java.lang.Float.parseFloat;
import static java.lang.Integer.parseInt;
public class Validation {
static int principal;
public static Integer checkPrincipalValidation(Scanner scanner) {
while (true) {
if (scanner.hasNextInt()) {
principal = parseInt(scanner.nextLine());
if (principal >= 1_000 && principal <= 1_000_000) {
break;
}
System.out.println(scanner.nextLine() + " is not between 1,000 and 1,000,000. Please enter correct Principal (1K - $1M):");
}
if (!scanner.hasNextInt()) {
System.out.println(scanner.nextLine() + " is not a valid integer. Please enter correct Principal (Integer):");
}
}
return principal;
}
public static Float checkInterestValidation(Scanner scanner) {
while (true) {
if (scanner.hasNextFloat() || scanner.hasNextInt()) {
if (scanner.hasNextInt()) {
return parseFloat(scanner.nextLine());
}
return scanner.nextFloat();
} else {
System.out.println(scanner.nextLine() + " is not a valid rate");
System.out.print("Please enter correct Rate: ");
}
}
}
public static Integer checkPeriodValidation(Scanner scanner) {
while (true) {
if (scanner.hasNextInt()) {
return scanner.nextInt();
} else {
System.out.println(scanner.nextLine() + " is not a valid period");
System.out.print("Please enter correct Period (Years): ");
}
}
}
}
When it passes through the first "if-statement", I have to enter the number twice before it goes into the second "if-statement". Why? Thank you for your time. I took a year off of coding so I'm extremely rusty and still extremely new to java, haha!
Every time you call scanner.nextLine() you must provide additional input.
Let me write comments to your method to show you the points:
public static Integer checkPrincipalValidation(Scanner scanner) {
while (true) {
if (scanner.hasNextInt()) { // (1)
principal = parseInt(scanner.nextLine()); // (2)
if (principal >= 1_000 && principal <= 1_000_000) {
break;
}
// (3) is the next line
System.out.println(scanner.nextLine() + " is not between 1,000 and 1,000,000. Please enter correct Principal (1K - $1M):");
}
if (!scanner.hasNextInt()) { // (4)
// (5) is the next line
System.out.println(scanner.nextLine() + " is not a valid integer. Please enter correct Principal (Integer):");
}
}
return principal;
}
On the code line marked (1) you check whether the input contains a valid integer value.
If it is then at the code line (2) you read that value, parse it and store the value in principal.
Then, if the value for the principal is outside of the valid range, you read the next line of input at code line (3). This is not the same value as the one that you have read at code line (2) - that value was consumed and cannot be retrieved a second time!
Then at code line (4) you check again if the next value from the input is a valid integer value. If there is no valid integer value, you consume that input at code line (5).
The total effect is this:
If the user enters for example a value "1" that value passes the condition on code line (1), is read from the input and parsed into an int value at code line (2).
Since this value is not in the valid range of 1000 <= value <= 1_000_000 the code continues to line (3) where you require the user to input an additional line so that you can tell him that this new input is not between 1,000 and 1,000,000
Then the code progresses to code line (4), expecting an additional input.
To fix this mess you should rewrite your code maybe like this:
public static int checkPrincipalValidation(Scanner scanner) {
while (true) {
if (scanner.hasNextInt()) {
principal = scanner.nextInt();
if (principal >= 1_000 && principal <= 1_000_000) {
break;
}
System.out.println(principal + " is not between 1,000 and 1,000,000. Please enter correct Principal (1K - $1M):");
} else {
System.out.println(scanner.nextLine() + " is not a valid integer. Please enter correct Principal (Integer):");
}
}
return principal;
}
Note that although this code solves your immediate problem, you might later on encounter additional problems when you read the following input with scanner.nextLine() - see the answer at Scanner is skipping nextLine() after using next() or nextFoo() for more information.
The gist of that question and answers: it is surprisingly difficult to use a Scanner if your input contains mixed input (single tokens like numbers or single words on the one hand and complete lines of input on the other hand).

java.lang.StackOverflowError on recursive function call

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();

Incompatible operand types String and int

Just a code of a bank with few functions, I am only trying to learn the way if loops are made. Seem to be getting "Incompatible operand types String and int" error on all lines that have an if,else if.
import java.util.Scanner;
public class Bank
{
//create variables
int pac;
int confirm;
int pin;
int Bal_or_Exit;
public static void main(String args[])
{
//Receive any PAC and create if loop for continue or exit
Scanner in = new Scanner(System.in);
System.out.println("Please Enter your Personal Access Code (P.A.C)");
String pac = in.nextLine();
System.out.println(pac + " is the P.A.C you have just entered.");
System.out.println("Press 1 to continue, Press 2 to cancel");
String confirm = in.nextLine();
if(confirm == 1)
//if loop created for confirm or exit...create another if loop for a pin of 0207
{
System.out.println("Please Enter your Pin");
String pin = in.nextLine();
if(pin == 0207)
//if loop created for pin, only access if pin=0207..access granted and
option of viewing Account Balance or Exit
{
System.out.println("Welcome!");
System.out.println("Press 1 for Balance");
System.out.println("Press 2 to Exit");
String Bal_or_Exit = in.nextLine();
//if 1 is pressed, display balance of €2965.33
if(Bal_or_Exit == 1)
{
System.out.println("Your balance is €2965.33");
}
//if 2 is pressed, display goodbye message
else if(Bal_or_Exit == 2)
{
System.out.println("GoodBye, Have a Nice a Day!");
}
//if anything else is pressed display error message
else
{
System.out.println("We're Sorry, An Error has Occured");
}
}
//if pin is anything except 0207 , display wrong pin message
else
{
System.out.println("The PIN you Have entered is incorrect");
}
}
//if confirm = 2 (exit), display exit and goodbye message
else if(confirm == 2)
{
System.out.println("You have selected exit");
System.out.println("Have a Nice Day!");
}
//if confirm is not = 1 or 2, display error message
else
{
System.out.println("We're Sorry, An Error has Occured");
}
}
}
You have that error due to Scanner#nextLine() returns a String, so, when you call:
String confirm = in.nextLine();
confirm is a String and then you're trying to compare:
if(confirm == 1)
In other words:
if (String == int)
You should either:
Call Scanner#nextInt()
Change your if as follows:
if (confirm.equals("1"))
There are multiple problems with your code. Take if(pin == 0207) as an example:
pin is a string so it can't be compared to a number like that
strings need to be compared via equals() and not ==
0207 is an octal literal, i.e. in decimal it would be the number 135.
To fix that change pin == 0207 to pin.equals( "0207" ) and the other string comparisons such as confirm == 1 accordingly too.
You could also try to parse the strings to numbers, e.g. Integer.parseInt( confirm) == 1 but since 0207 is probably meant to be used as it is you need to use String here anyways.
You can't compare a string with an integer because they are two different data types. You will have to cast the string to an integer to do this.
Like this:
if(Integer.parseInt( confirm ) == 1)
Alternatively you can cast the user input before storing it in the string variable.
int confirm = Integer.parseInt(in.nextLine());
You can also read the user input as an integer instead of a string.
int confirm = in.nextInt();
For the value 0207 it would be more sensible to compare it as a string because of the leading 0. This information would get lost if you compare it as an integer. To compare strings you can use the equals() method.
if(pin.equals("0207"))

Java validate only values between 1 and 3

I am trying to only accept integers between the values of 1 and 3 using a while loop and nested if statement in Java.
Anything outside of this range, produces an error message
The program should only accept integers between 1 and 3, any strings of text or decimal values should also produce the same error message and loop back to the original print statement (enter a number: )
The code below runs without any compiler errors although the statement || (a < 1 || a > 3)) will always produce the error message, regardless of the value.
If I was to delete this statement, the program will run and only accept integers of any value, (error message appearing when a string or decimal value is entered)
Could anyone help range this program, only accepting values of between 1 and 3, thanks.
import java.util.Scanner;
public class Validate {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int a = 0;
while (true) {
System.out.print("enter a number: ");
if (!input.hasNextInt() || !input.hasNext() || (a < 1 || a > 3)) {
System.out.println("Oops! ");
input.nextLine();
}
else {
a = input.nextInt();
break;
}
}
input.close();
System.out.println("a = " + a);
}
}
Make sure to be careful of the order of expressions. If one of the 3 statements you wrote happens to be true then the code in the if curly braces will execute. You likely want something like this
if (!input.hasNextInt() || !input.hasNext()){
if ((a > 1 || a < 3)){
YourCode
}
}
The biggest issue is that you need to remember that initially your integer "a" is set to "0". This always catches your first if condition meaning that a is never set!
You are not updating the value of a, so it's 0 all the time.
import java.util.Scanner;
public class Validate {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int a = 0;
boolean loop = true;
while (loop) {
System.out.print("enter a number: ");
if (!input.hasNextInt() || !input.hasNext()) {
System.out.println("Oops! ");
input.nextLine();
} else {
a = input.nextInt();
if (a <= 3 && a >= 1)
loop = false;
else {
System.out.println("Oops! ");
input.nextLine();
}
}
}
input.close();
System.out.println("a = " + a);
}
}
EDIT:

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