So far I have this:
public double checkValueWithin(int min, int max) {
double num;
Scanner reader = new Scanner(System.in);
num = reader.nextDouble();
while (num < min || num > max) {
System.out.print("Invalid. Re-enter number: ");
num = reader.nextDouble();
}
return num;
}
and this:
public void askForMarks() {
double marks[] = new double[student];
int index = 0;
Scanner reader = new Scanner(System.in);
while (index < student) {
System.out.print("Please enter a mark (0..30): ");
marks[index] = (double) checkValueWithin(0, 30);
index++;
}
}
When I test this, it can't take double number and I got this message:
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:909)
at java.util.Scanner.next(Scanner.java:1530)
at java.util.Scanner.nextDouble(Scanner.java:2456)
at MarkingSystem.checkValueWithin(MarkingSystem.java:25)
at MarkingSystem.askForMarks(MarkingSystem.java:44)
at World.main(World.java:6)
Java Result: 1
How do I fix this?
Instead of using a dot, like: 1.2, try to input like this: 1,2.
Here you can see the nature of Scanner:
double nextDouble()
Returns the next token as a double. If the next token is not a float or
is out of range, InputMismatchException is thrown.
Try to catch the exception
try {
// ...
} catch (InputMismatchException e) {
System.out.print(e.getMessage()); //try to find out specific reason.
}
UPDATE
CASE 1
I tried your code and there is nothing wrong with it. Your are getting that error because you must have entered String value. When I entered a numeric value, it runs without any errors. But once I entered String it throw the same Exception which you have mentioned in your question.
CASE 2
You have entered something, which is out of range as I have mentioned above.
I'm really wondering what you could have tried to enter. In my system, it is running perfectly without changing a single line of code. Just copy as it is and try to compile and run it.
import java.util.*;
public class Test {
public static void main(String... args) {
new Test().askForMarks(5);
}
public void askForMarks(int student) {
double marks[] = new double[student];
int index = 0;
Scanner reader = new Scanner(System.in);
while (index < student) {
System.out.print("Please enter a mark (0..30): ");
marks[index] = (double) checkValueWithin(0, 30);
index++;
}
}
public double checkValueWithin(int min, int max) {
double num;
Scanner reader = new Scanner(System.in);
num = reader.nextDouble();
while (num < min || num > max) {
System.out.print("Invalid. Re-enter number: ");
num = reader.nextDouble();
}
return num;
}
}
As you said, you have tried to enter 1.0, 2.8 and etc. Please try with this code.
Note : Please enter number one by one, on separate lines. I mean, enter 2.7, press enter and then enter second number (e.g. 6.7).
I encountered the same problem.
Strange, but the reason was that the object Scanner interprets fractions depending on localization of system.
If the current localization uses a comma to separate parts of the fractions, the fraction with the dot will turn into type String.
Hence the error ...
Since you have the manual user input loop, after the scanner has read your first input it will pass the carriage/return into the next line which will also be read; of course, that is not what you wanted.
You can try this
try {
// ...
} catch (InputMismatchException e) {
reader.next();
}
or alternatively, you can consume that carriage return before reading your next double input by calling
reader.next()
Are you providing write input to the console ?
Scanner reader = new Scanner(System.in);
num = reader.nextDouble();
This is return double if you just enter number like 456.
In case you enter a string or character instead,it will throw java.util.InputMismatchException when it tries to do num = reader.nextDouble() .
Related
This question already has an answer here:
While loop to determine if entered value is a double
(1 answer)
Closed 1 year ago.
I know there are lots of questions similar to this but I can't understand most of it, also I can't see any similar questions related to java language.
So can you guys help me how to loop this question if the input is not a double data type?
The code:
System.out.println("Enter first number");
num1 = input.nextDouble();
System.out.println("Enter second number");
num2 = input.nextDouble();
I really appreciate anyone who tries to answer, tia!!
This is a solution (without exception handling). It loops until two Doubles have been entered. So it is possible to enter this:
3
4.2
or also:
www
3
abc
4.2
Both will give the same result
3
4.2
Note that the code is locale sensitive in regard of the numbers you enter at the command prompt (meaning that the decimal sign depends on your computer settings – in Germany for example it is the comma and not the dot, so you would enter 4,2):
Scanner scanner = new Scanner(System.in);
Double part1 = null;
Double part2 = null;
while (true) {
if (scanner.hasNextDouble()) {
if (part1 == null ) {
part1 = scanner.nextDouble();
} else {
part2 = scanner.nextDouble();
break;
}
} else {
scanner.next(); // The input is not a Double, so just drop it
}
}
scanner.close();
System.out.println(part1);
System.out.println(part2);
If you add the line scanner.useLocale(Locale.ROOT) after creating the scanner:
Scanner scanner = new Scanner(System.in);
scanner.useLocale(Locale.ROOT);
the decimal sign will be the dot '.' like in 4.2 independent of the settings of your computer.
I like to create a separate method to validate input. If the value is invalid, then I have the method return -1. Then I'll have a while loop that checks if the input is -1, if so, than it'll ask the for a new input value till it's correct. There are many ways to go about it. But the gist is something like this.
public static void main(String[] Args) {
Scanner input = new Scanner(System.in);
System.out.println("Enter first number");
double num1 = validateDouble(input);
while (num1 == -1) {
num1 = validateDouble(input);
}
System.out.println(num1);
}
private static double validateDouble(Scanner scanner) {
String input = scanner.nextLine();
try {
double i = Double.parseDouble(input);;
return i;
}catch (InputMismatchException | NumberFormatException e) {
if (input.equals("q")) {
System.exit(0);
}
System.out.println("Please try again.");
return -1;
}
}
So far I have this:
public double checkValueWithin(int min, int max) {
double num;
Scanner reader = new Scanner(System.in);
num = reader.nextDouble();
while (num < min || num > max) {
System.out.print("Invalid. Re-enter number: ");
num = reader.nextDouble();
}
return num;
}
and this:
public void askForMarks() {
double marks[] = new double[student];
int index = 0;
Scanner reader = new Scanner(System.in);
while (index < student) {
System.out.print("Please enter a mark (0..30): ");
marks[index] = (double) checkValueWithin(0, 30);
index++;
}
}
When I test this, it can't take double number and I got this message:
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:909)
at java.util.Scanner.next(Scanner.java:1530)
at java.util.Scanner.nextDouble(Scanner.java:2456)
at MarkingSystem.checkValueWithin(MarkingSystem.java:25)
at MarkingSystem.askForMarks(MarkingSystem.java:44)
at World.main(World.java:6)
Java Result: 1
How do I fix this?
Instead of using a dot, like: 1.2, try to input like this: 1,2.
Here you can see the nature of Scanner:
double nextDouble()
Returns the next token as a double. If the next token is not a float or
is out of range, InputMismatchException is thrown.
Try to catch the exception
try {
// ...
} catch (InputMismatchException e) {
System.out.print(e.getMessage()); //try to find out specific reason.
}
UPDATE
CASE 1
I tried your code and there is nothing wrong with it. Your are getting that error because you must have entered String value. When I entered a numeric value, it runs without any errors. But once I entered String it throw the same Exception which you have mentioned in your question.
CASE 2
You have entered something, which is out of range as I have mentioned above.
I'm really wondering what you could have tried to enter. In my system, it is running perfectly without changing a single line of code. Just copy as it is and try to compile and run it.
import java.util.*;
public class Test {
public static void main(String... args) {
new Test().askForMarks(5);
}
public void askForMarks(int student) {
double marks[] = new double[student];
int index = 0;
Scanner reader = new Scanner(System.in);
while (index < student) {
System.out.print("Please enter a mark (0..30): ");
marks[index] = (double) checkValueWithin(0, 30);
index++;
}
}
public double checkValueWithin(int min, int max) {
double num;
Scanner reader = new Scanner(System.in);
num = reader.nextDouble();
while (num < min || num > max) {
System.out.print("Invalid. Re-enter number: ");
num = reader.nextDouble();
}
return num;
}
}
As you said, you have tried to enter 1.0, 2.8 and etc. Please try with this code.
Note : Please enter number one by one, on separate lines. I mean, enter 2.7, press enter and then enter second number (e.g. 6.7).
I encountered the same problem.
Strange, but the reason was that the object Scanner interprets fractions depending on localization of system.
If the current localization uses a comma to separate parts of the fractions, the fraction with the dot will turn into type String.
Hence the error ...
Since you have the manual user input loop, after the scanner has read your first input it will pass the carriage/return into the next line which will also be read; of course, that is not what you wanted.
You can try this
try {
// ...
} catch (InputMismatchException e) {
reader.next();
}
or alternatively, you can consume that carriage return before reading your next double input by calling
reader.next()
Are you providing write input to the console ?
Scanner reader = new Scanner(System.in);
num = reader.nextDouble();
This is return double if you just enter number like 456.
In case you enter a string or character instead,it will throw java.util.InputMismatchException when it tries to do num = reader.nextDouble() .
This question already has answers here:
How to handle infinite loop caused by invalid input (InputMismatchException) using Scanner
(5 answers)
Closed last month.
So I'm building a program which takes ints from user input. I have what seems to be a very straightforward try/catch block which, if the user doesn't enter an int, should repeat the block until they do. Here's the relevant part of the code:
import java.util.InputMismatchException;
import java.util.Scanner;
public class Except {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
boolean bError = true;
int n1 = 0, n2 = 0, nQuotient = 0;
do {
try {
System.out.println("Enter first num: ");
n1 = input.nextInt();
System.out.println("Enter second num: ");
n2 = input.nextInt();
nQuotient = n1/n2;
bError = false;
}
catch (Exception e) {
System.out.println("Error!");
}
} while (bError);
System.out.printf("%d/%d = %d",n1,n2, nQuotient);
}
}
If I enter a 0 for the second integer, then the try/catch does exactly what it's supposed to and makes me put it in again. But, if I have an InputMismatchException like by entering 5.5 for one of the numbers, it just shows my error message in an infinite loop. Why is this happening, and what can I do about it? (By the way, I have tried explicitly typing InputMismatchException as the argument to catch, but it didn't fix the problem.
You need to call next(); when you get the error. Also it is advisable to use hasNextInt()
catch (Exception e) {
System.out.println("Error!");
input.next();// Move to next other wise exception
}
Before reading integer value you need to make sure scanner has one. And you will not need exception handling like that.
Scanner scanner = new Scanner(System.in);
int n1 = 0, n2 = 0;
boolean bError = true;
while (bError) {
if (scanner.hasNextInt())
n1 = scanner.nextInt();
else {
scanner.next();
continue;
}
if (scanner.hasNextInt())
n2 = scanner.nextInt();
else {
scanner.next();
continue;
}
bError = false;
}
System.out.println(n1);
System.out.println(n2);
Javadoc of Scanner
When a scanner throws an InputMismatchException, the scanner will not pass the token that caused the exception, so that it may be retrieved or skipped via some other method.
YOu can also try the following
do {
try {
System.out.println("Enter first num: ");
n1 = Integer.parseInt(input.next());
System.out.println("Enter second num: ");
n2 = Integer.parseInt(input.next());
nQuotient = n1/n2;
bError = false;
}
catch (Exception e) {
System.out.println("Error!");
input.reset();
}
} while (bError);
another option is to define Scanner input = new Scanner(System.in); inside the try block, this will create a new object each time you need to re-enter the values.
To follow debobroto das's answer you can also put after
input.reset();
input.next();
I had the same problem and when I tried this. It completely fixed it.
As the bError = false statement is never reached in the try block, and the statement is struck to the input taken, it keeps printing the error in infinite loop.
Try using it this way by using hasNextInt()
catch (Exception e) {
System.out.println("Error!");
input.hasNextInt();
}
Or try using nextLine() coupled with Integer.parseInt() for taking input....
Scanner scan = new Scanner(System.in);
int num1 = Integer.parseInt(scan.nextLine());
int num2 = Integer.parseInt(scan.nextLine());
To complement the AmitD answer:
Just copy/pasted your program and had this output:
Error!
Enter first num:
.... infinite times ....
As you can see, the instruction:
n1 = input.nextInt();
Is continuously throwing the Exception when your double number is entered, and that's because your stream is not cleared. To fix it, follow the AmitD answer.
#Limp, your answer is right, just use .nextLine() while reading the input. Sample code:
do {
try {
System.out.println("Enter first num: ");
n1 = Integer.parseInt(input.nextLine());
System.out.println("Enter second num: ");
n2 = Integer.parseInt(input.nextLine());
nQuotient = n1 / n2;
bError = false;
} catch (Exception e) {
System.out.println("Error!");
}
} while (bError);
System.out.printf("%d/%d = %d", n1, n2, nQuotient);
Read the description of why this problem was caused in the link below. Look for the answer I posted for the detail in this thread.
Java Homework user input issue
Ok, I will briefly describe it. When you read input using nextInt(), you just read the number part but the ENDLINE character was still on the stream. That was the main cause. Now look at the code above, all I did is read the whole line and parse it , it still throws the exception and work the way you were expecting it to work. Rest of your code works fine.
I want to make it so that a user entering the wrong data type as figureNumber will see a message from me saying "Please enter an integer" instead of the normal error message, and will be given another chance to enter an integer. I started out trying to use try and catch, but I couldn't get it to work.
Sorry if this is a dumb question. It's my second week of an intro to java class.
import java. util.*;
public class Grades {
public static void main(String args []) {
Scanner stdin = new Scanner(System.in);
System.out.println();
System.out.print(" Please enter an integer: ");
int grade = stdin.nextInt();
method2 ();
if (grade % 2 == 0) {
grade -= 1;
}
for(int i = 1; i <=(grade/2); i++) {
method1 ();
method3 ();
}
}
}
public static void main(String args[]) {
Scanner stdin = new Scanner(System.in);
System.out.println();
System.out.print(" Welcome! Please enter the number of figures for your totem pole: ");
while (!stdin.hasNextInt()) {
System.out.print("That's not a number! Please enter a number: ");
stdin.next();
}
int figureNumber = stdin.nextInt();
eagle();
if (figureNumber % 2 == 0) { //determines if input number of figures is even
figureNumber -= 1;
}
for (int i = 1; i <= (figureNumber / 2); i++) {
whale();
human();
}
}
You need to check the input. The hasNextInt() method is true if the input is an integer. So this while loop asks the user to enter a number until the input is a number. Calling next() method is important because it will remove the previous wrong input from the Scanner.
Scanner stdin = new Scanner(System.in);
try {
int figureNumber = stdin.nextInt();
eagle();
if (figureNumber % 2 == 0) { //determines if input number of figures is even
figureNumber -= 1;
}
for(int i = 1; i <=(figureNumber/2); i++) {
whale();
human();
}
}
catch (InputMismatchException e) {
System.out.print("Input must be an integer");
}
You probably want to do something like this. Don't forget to add import java.util.*; at the beginning of .java file.
You want something in the form:
Ask for input
If input incorrect, say so and go to step 1.
A good choice is:
Integer num = null; // define scope outside the loop
System.out.println("Please enter a number:"); // opening output, done once
do {
String str = scanner.nextLine(); // read anything
if (str.matches("[0-9]+")) // if it's all digits
num = Integer.parseInt(str);
else
System.out.println("That is not a number. Please try again:");
} while (num == null);
// if you get to here, num is a number for sure
A do while is a good choice because you always at least one iteration.
It's important to read the whole line as a String. If you try to read an int and one isn't there the call will explode.
You can actually test the value before you assign it. You don't need to do any matching.
...
int figureNumber = -1;
while (figureNumber < 0) {
System.out.print(" Welcome! Please enter the number of figures for your totem pole: ");
if (stdin.hasNextInt()){
figureNumber = stdin.nextInt(); //will loop again if <0
} else {
std.next(); //discard the token
System.out.println("Hey! That wasn't an integer! Try again!");
}
}
...
I'm trying to make a small program more robust and I need some help with that.
Scanner kb = new Scanner(System.in);
int num1;
int num2 = 0;
System.out.print("Enter number 1: ");
num1 = kb.nextInt();
while(num2 < num1) {
System.out.print("Enter number 2: ");
num2 = kb.nextInt();
}
Number 2 has to be greater than number 1
Also I want the program to automatically check and ignore if the user enters a character instead of a number. Because right now when a user enters for example r instead of a number the program just exits.
Use Scanner.hasNextInt():
Returns true if the next token in this scanner's input can be interpreted as an int value in the default radix using the nextInt() method. The scanner does not advance past any input.
Here's a snippet to illustrate:
Scanner sc = new Scanner(System.in);
System.out.print("Enter number 1: ");
while (!sc.hasNextInt()) sc.next();
int num1 = sc.nextInt();
int num2;
System.out.print("Enter number 2: ");
do {
while (!sc.hasNextInt()) sc.next();
num2 = sc.nextInt();
} while (num2 < num1);
System.out.println(num1 + " " + num2);
You don't have to parseInt or worry about NumberFormatException. Note that since the hasNextXXX methods don't advance past any input, you may have to call next() if you want to skip past the "garbage", as shown above.
Related questions
How do I keep a scanner from throwing exceptions when the wrong type is entered? (java)
the condition num2 < num1 should be num2 <= num1 if num2 has to be greater than num1
not knowing what the kb object is, I'd read a String and then trying Integer.parseInt() and if you don't catch an exception then it's a number, if you do, read a new one, maybe by setting num2 to Integer.MIN_VALUE and using the same type of logic in your example.
This should work:
import java.util.Scanner;
public class Test {
public static void main(String... args) throws Throwable {
Scanner kb = new Scanner(System.in);
int num1;
System.out.print("Enter number 1: ");
while (true)
try {
num1 = Integer.parseInt(kb.nextLine());
break;
} catch (NumberFormatException nfe) {
System.out.print("Try again: ");
}
int num2;
do {
System.out.print("Enter number 2: ");
while (true)
try {
num2 = Integer.parseInt(kb.nextLine());
break;
} catch (NumberFormatException nfe) {
System.out.print("Try again: ");
}
} while (num2 < num1);
}
}
Try this:
public static void main(String[] args)
{
Pattern p = Pattern.compile("^\\d+$");
Scanner kb = new Scanner(System.in);
int num1;
int num2 = 0;
String temp;
Matcher numberMatcher;
System.out.print("Enter number 1: ");
try
{
num1 = kb.nextInt();
}
catch (java.util.InputMismatchException e)
{
System.out.println("Invalid Input");
//
return;
}
while(num2<num1)
{
System.out.print("Enter number 2: ");
temp = kb.next();
numberMatcher = p.matcher(temp);
if (numberMatcher.matches())
{
num2 = Integer.parseInt(temp);
}
else
{
System.out.println("Invalid Number");
}
}
}
You could try to parse the string into an int as well, but usually people try to avoid throwing exceptions.
What I have done is that I have defined a regular expression that defines a number, \d means a numeric digit. The + sign means that there has to be one or more numeric digits. The extra \ in front of the \d is because in java, the \ is a special character, so it has to be escaped.
I see that Character.isDigit perfectly suits the need, since the input will be just one symbol.
Of course we don't have any info about this kb object but just in case it's a java.util.Scanner instance, I'd also suggest using java.io.InputStreamReader for command line input. Here's an example:
java.io.BufferedReader reader = new java.io.BufferedReader(new java.io.InputStreamReader(System.in));
try {
reader.read();
}
catch(Exception e) {
e.printStackTrace();
}
reader.close();
What you could do is also to take the next token as a String, converts this string to a char array and test that each character in the array is a digit.
I think that's correct, if you don't want to deal with the exceptions.