When I run this program i get the error Exception in thread "main" java.lang.NumberFormatException: empty String. Is it possible to make this work by throwing the exception some how or must I use a try catch statement?
private double[] scores3 = new double[5];
Scanner keyboard = new Scanner(System.in);
public void enterData()
{
double score;
double numberMin = 0;
double numberMax = 100;
do{
System.out.println("Enter the student's third test score");
while (!keyboard.hasNextDouble()) {
keyboard.next();
}
score3 = keyboard.nextDouble();
}
while (score3 <= numberMin || score3 >= numberMax);
double score3 = Double.parseDouble(keyboard.nextLine());
Before parsing a String to a Number.. compare the string with " " or use isEmpty() function to check if its a empty string or not !
Example:
if (myString.isEmpty()) {
//Do Nothing
} else {
//Code to perform calculations
}
or
if (!myString.isEmpty()) {
//Code to perform calculations
}
To your question of if you can throw the error elsewhere, you could do that by declaring
public void enterData() throws NumberFormatException
However I would recommend using a try catch block if you want to continue iterating over your while statements.
Related
I'm creating an application for a homework, the problem is that I am trying to create a do-while loop to exit the application (Using the question "Do you want to exit (Y/N)"). To work with the do-while loop, I created a method to store the app and then called the method in the do-while loop, so that when I try to stop the loop, the method loops once more. I want when I type "Y" to the console the whole program stops and doesn't loop one more time.
I created a simple example to explain my problem.
Here's the method:
public static void App(){
Scanner sc = new Scanner(System.in);
System.out.print("Write a number: ");
int num1 = sc.nextInt();
System.out.print("Write another number: ");
int num2 = sc.nextInt();
System.out.println("\nResult: "+(num1+num2));
}
And here I'm trying to create the loop in the main method:
public static void main(String[] args) {
Scanner sc2 = new Scanner(System.in);
App();
String answer;
do {
System.out.println("Do you want to exit (Y/N)?");
answer = sc2.next();
App();
} while (answer.equalsIgnoreCase("N")) ;
}
the problem is that I am trying to create a do-while loop to exit the application
You already have that in your program.
so that when I try to stop the loop, the method loops once more...
That doesn't fit the goal of your program.
I want when I type "Y" to the console the whole program stops and doesn't loop one more time
A lot of context that doesn't fit right in.
But anyway, you just have to reorganize your program.
In other words, just move your App() method.
public static void main(String[] args) {
Scanner sc2 = new Scanner(System.in);
String answer;
do {
App();
System.out.println("Do you want to exit (Y/N)?");
answer = sc2.next();
} while (answer.equalsIgnoreCase("N")) ;
}
Also, I spotted a lot of bad practices, so I kind of fixed them:
public static void main(String[] args) throws Exception {
try(Scanner sc2 = new Scanner(System.in)){
String answer;
do {
App();
System.out.print("Do you want to exit (Y/N)?");
answer = sc2.nextLine();
} while (answer.equalsIgnoreCase("N")) ;
}
}
Lastly, maybe (just maybe) try to solve your problem first before seeking help for your homework.
The reason why your program is running again after you type n is because the App() method is ran after the question is asked within the do part of the loop.
This code below is the simplest fix I could think of.
public static void main(String[] args) {
Scanner sc2 = new Scanner(System.in);
// I removed the line 'App();' as the App method will always run at least one time. Therefore putting that method within the 'do' part of the loop allows us to ask the user if they wish to exit or not after they have received their answer.
String answer;
do {
App();
System.out.print("Do you want to exit (Y/N)?"); //I changed the 'println' to 'print' here
answer = sc2.next();
} while (answer.equalsIgnoreCase("N")) ;
}
As a side note, methods in java should be lower-case when following typical Java naming conventions. While this will not affect how your code runs, I would suggest renaming the method from App() to app().
Everything looks good in your code, Just change the execution logic as shown in code blocks.
public static void main(String[] args) {
Scanner sc2 = new Scanner(System.in);
App(); //remove this line from here
String answer;
do {
App(); //call App function here so that it got executed at least one time
System.out.println("Do you want to exit (Y/N)?");
answer = sc2.next();
App(); //remove this as well
} while (answer.equalsIgnoreCase("N")) ;
}
Here is yet another approach except it uses a while loops instead of do/while loops. Two different approaches are provided and both provide User entry validation:
Approach #1:
public static void appMethod() {
Scanner sc = new Scanner(System.in);
int num1 = Integer.MIN_VALUE; // Initialize with some obscure value.
int num2 = Integer.MIN_VALUE; // Initialize with some obscure value.
while (num1 == Integer.MIN_VALUE) {
System.out.print("Write a number: ");
try {
num1 = sc.nextInt();
} catch ( java.util.InputMismatchException ex) {
System.out.println("Invalid Entry! Try again..."
+ System.lineSeparator());
sc.nextLine(); // consume the ENTER key hit otherwise this error will keep cycling.
num1 = Integer.MIN_VALUE;
}
}
while (num2 == Integer.MIN_VALUE) {
System.out.print("Now, write yet another number: ");
try {
num2 = sc.nextInt();
} catch ( java.util.InputMismatchException ex) {
System.out.println("Invalid Entry! Try again..."
+ System.lineSeparator());
sc.nextLine(); // consume the ENTER key hit otherwise this error will keep cycling.
num2 = Integer.MIN_VALUE;
}
}
System.out.println("\nResult: " + num1 +" + " + num2 + " = " + (num1 + num2));
}
Approach #2:
This next approach makes use of the Scanner#nextLine() method. The thing to remember about nextLine() is that, if you use it in your console application then basically recommend you use it for everything (all prompts). A 'quit' mechanism is also available in this version. Read the comments in code:
public static void appMethod() {
Scanner sc = new Scanner(System.in);
// Retrieve first number...
String num1 = "";
while (num1.isEmpty()) {
System.out.print("Write a number (q to quit): ");
// Making use of the Scanner#nextLine() method
num1 = sc.nextLine();
// Has 'q' been supplied to Quit?
if (num1.equalsIgnoreCase("q")) {
return;
}
/* Validate the fact that a signed or unsigned Integer or
Floating Point value has been entered. If not show Msg. */
if (!num1.matches("-?\\d+(\\.\\d+)?")) {
System.out.println("Invalid Entry! (" + num1 + ") Try again..."
+ System.lineSeparator());
num1 = ""; // empty num1 so as to re-loop.
}
}
// Retrieve second number...
String num2 = "";
while (num2.isEmpty()) {
System.out.print("Now, write yet another number (q to quit): ");
num2 = sc.nextLine();
if (num2.equalsIgnoreCase("q")) {
return;
}
if (!num2.matches("-?\\d+(\\.\\d+)?")) {
System.out.println("Invalid Entry! (" + num2 + ") Try again..."
+ System.lineSeparator());
num2 = "";
}
}
// Convert the numerical strings to double data type values.
double number1 = Double.parseDouble(num1);
double number2 = Double.parseDouble(num2);
// Display the result.
System.out.println("\nResult: " + num1 +" + " + num2 + " = " + (number1 + number2));
}
I'm trying to write a function to validate the user's input. It only returns when the user inputs a double number.
private static double getDouble(String name) {
double res = 0;
Scanner s = new Scanner(System.in);
while (true) {
System.out.println("Please input " + name + ":");
if (s.hasNextDouble()) {
res = s.nextDouble();
break;
}
else s.nextLine();
}
s.close();
return res;
}
However, it only works first time. If I call the function second time right after the first time, the nextLine() will throw an exception.
double length = 0, width = 0;
length = getDouble("length of picture");
width = getDouble("width of picture");
Please see the
Could someone tell me what the mistake I have made here? And how to fix/avoid it?
Thank you.
I have made another way for getting user input. Just refer to the code and code comments for details.
private static double getDouble(String name) {
double res = 0;
Scanner s = new Scanner(System.in);
while (true) {
try {
System.out.print("Please input " + name + ":");
res = Double.parseDouble(s.nextLine()); // Just get the user input as a string then try to convert it into a double
break; // if there is no error in the string to double conversion it means that the input is valid, thus break the loop
} catch (Exception e) { // catch possible errors in case the input is invalid
System.out.println("Your input is invalid!"); // print desired error message then the loop will execute again getting another user input
}
}
s.close();
return res;
}
EDIT
It is because you have close the scanner instance after the method. Refer to this why that won't work. You could also refer to that for alternatives.
If you want to use hasNextDouble then you could either pass the scanner as a parameter to your getDouble method or declare the scanner as a class variable. Both will result to only declaring and closing 1 Scanner.
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
double tmp = getDouble(s, "Tmp");
double tmp2 = getDouble(s, "Tmp");
s.close();
}
private static double getDouble(Scanner s, String name) {
double res = 0;
while (true) {
System.out.println("Please input " + name + ":");
if (s.hasNextDouble()) {
res = s.nextDouble();
break;
} else
s.nextLine();
}
return res;
}
When you close the Scanner object (s.close();) for System.in you can't use scanner again until you restart your application. It's best to leave the Scanner object open until you are absolutely sure you won't need it again.
Personally, I really don't like purposely relying on exceptions to take care of invalid situation but in this case it's extremely suited for it:
private static double getDouble(String name) {
double res = 0.0d;
Scanner s = new Scanner(System.in);
while (res == 0.0d) {
System.out.print("Please input " + name + ": --> ");
try {
res = s.nextDouble();
}
catch (Exception e) {
// If input is invalid
System.out.println("Your input is invalid! Numerical Values Only!");
/* Clear the scanner buffer otherwise the response
above will continue to display over and over
again. */
s.nextLine();
res = 0.0d;
}
}
return res;
}
You can also do this without using an exception trap:
private static double getDouble(String name) {
String res = "";
Scanner s = new Scanner(System.in);
while (res.equals("")) {
System.out.print("Please input " + name + ": ");
res = s.nextLine();
/* If the User supplies anything that is NOT a string
representation of a signed or unsigned integer or
double type numerical value. A regular Expression is
used here with the String#matches() method. */
if (!res.matches("-?\\d+(\\.\\d+)?")) {
// Input is invalid...
System.out.println("Your input is invalid (" + res + ")! Only Integer or Double Type Numerical Values Are Allowed!");
res = "";
}
}
return Double.parseDouble(res);
}
The program asks for the user input for the double num 1 and double num 2
and if there is an exception I want it to ask again for the input of num 1 and num 2
public static void main (String[] args) {
Scanner sc = new Scanner(System.in);
double num1, num2;
int error = 0;
int text;
System.out.print("Enter 4 ");
text = sc.nextInt();
do{
try{
if(text == 4){
System.out.print("Enter number 1: ");
num1 = sc.nextDouble();
System.out.print("Enter number 2: ");
num2 = sc.nextDouble();
double quotient = num1/num2;
System.out.println("The Quotient of "+num1 + "/" +num2+ " = "+quotient);
}
}catch(Exception ex){
System.out.println("You've entered wrong input");
error = 1;
}
}while(error == 1);
}
then when I try the code if it will catch the exceptions by inputing string in the num1 or num 2 I'm having this infinite loop :
Enter number 1: You've entered wrong input
Enter number 1: You've entered wrong input
Enter number 1: You've entered wrong input
Enter number 1: You've entered wrong input
Enter number 1: You've entered wrong input
You need to reset the error variable inside the loop
do {
error = 0;
//...
} while(error == 1);
It is not necessary to utilize exception handling. Just use Scanner.hasNextDouble() method to find out if actual user input is double, otherwise continue the cycle.
package com.company;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
double num1, num2;
num1 = readDouble(1, sc);
num2 = readDouble(2, sc);
double quotient = num1/num2;
System.out.println("The Quotient of " + num1 + "/" + num2 + " = " + quotient);
}
private static double readDouble(int i, Scanner sc) {
while (true) {
System.out.print("Enter number " + i + ": ");
if (!sc.hasNextDouble()) {
System.out.println("You've entered wrong input");
sc.next();
continue;
}
break;
}
return sc.nextDouble();
}
}
Its in C# but relatively similar :)
public class Program
{
private static double ReadUserInput (string message)
{
// This is a double
// The '?' makes it nullable which is easier to work with
double? input = null;
do
{
// Write message out
Console.Write(message);
// Read answer
var inputString = Console.ReadLine();
// Temp variable for the number
double outputNumber = 0;
// Try parse the number
if (double.TryParse(inputString, out outputNumber))
{
// The number was parsable as a double so lets set the input variable
input = outputNumber;
}
else
{
// Tell the user the number was invalid
Console.WriteLine("Sorry bud, but '" + inputString + "' is not a valid double");
}
}
while (input == null); // Keep running until the input variable is actually set by the above
// Return the output
return (double)input;
}
public static void Main()
{
// Read a number
var num1 = ReadUserInput("Enter number 1:");
// Read another number
var num2 = ReadUserInput("Enter number 2:");
// Show the calculation
Console.WriteLine("Answer: " + (num1*num2));
}
}
Demo
And for the actual code (in JAVA):
public class JavaFiddle
{
public static void main (String[] args)
{
// Read a number
Double num1 = ReadUserInput("Enter number 1:");
// Read another number
Double num2 = ReadUserInput("Enter number 2:");
// Show the calculation
System.out.println("Answer: " + (num1*num2));
}
public static Double ReadUserInput (String message)
{
java.util.Scanner inputScanner = new java.util.Scanner(System.in);
Double input = null;
do
{
// Write message out
System.out.println(message);
// Read answer
String inputString = inputScanner.nextLine();
try
{
// Try parse the number
input = Double.parseDouble(inputString);
}
catch (NumberFormatException e)
{
// Tell the user the number was invalid
System.out.println("Sorry bud, but '" + inputString + "' is not a valid double");
}
}
while (input == null); // Keep running until the input variable is actually set by the above
// Return the output
return input;
}
}
You probably want to test if there is no error:
}while(error != 1);
or
}while(error == 0);
You'll need a method for the input which calls itself, if the input is invalid.
double getInput(Scanner sc) {
try {
double num = sc.nextDouble();
return num;
} catch(Exception ex) {
System.out.println("You've entered wrong input");
return getInput(sc);
}
}
And call this method twice in your other method.
it may look ugly , but here is a way to do it
do
{
if(...)
{
boolean successReading = false;
while(!successReading)
{
try
{
System.out.print("Enter number 1: ");
num1 = sc.nextDouble();
System.out.print("Enter number 2: ");
num2 = sc.nextDouble();
successReading = true;
double product = num1*num2;
}
catch(Exception e)
{
successReading = false;
}
}
}
}while(...)
You need to add sc.next(); inside catch block.
nextDouble method doesn't clear buffer in case of exception. So next time you invoke it you get same error because old input is still in buffer.
Also you need to reset your error flag in the beginning of the loop.
You have to put sc.next(); in the catch so it will clear your scanner variable and it will ask for an input
When using scanner is there a way to check that the user input is what we expect?
Say I want a double but the user enters a String what can I do to prompt the user to re-enter the value as a double?
With the following code if a number is not entered I get a mismatchException. I don't want the program to crash if the input is wrong.
Here is my code:
import java.util.Scanner;
public class RoundingNumbers {
private double y;
private double x;
public RoundingNumbers(){
double y = 0;
double x = 0;
}
public void getNumber(){
System.out.print("Enter a decimal number: ");
Scanner num = new Scanner(System.in);
x = num.nextDouble();
}
public void roundNum(){
y = Math.floor(x + 0.5);
}
public void displayNums(){
System.out.println("The actual number is: " + x);
System.out.println("The rounded number is: " + y);
}
}
You can wrap it in a try catch block. See the below example function.
Whoops. I wasn't paying close enough attention and didn't see your code example.
Change your getNumber() function to the below definition. Note that there are many different ways to do this. This is just an example.
public void getNumber(){
Scanner num = new Scanner(System.in);
while(true) {
System.out.print("Enter a decimal number: ");
try {
x = num.nextDouble();
break;
catch(InputMismatchException e) {}
}
}
You already noticed that you recieve a InputMismatchException if they don't type what you expect. With this in mind, you can surround the x = num.nextDouble() with a try-catch block and check for that kind of Exception. For example:
while (true) {
try {
x = num.nextDouble();
// move along if no exception is thrown
break;
} catch (InputMismatchException e) {
// give the user an error message
System.out.println("Type mismatch when reading your input. Please insert a double: ");
}
}
By the way, this is not directly related to your question, but you shouldn't name your Scanner variable as num, because that name doesn't make anyone think of a Scanner - people in general would think it's an int or something. It's a good programming practice to give your variables names that fits them.
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() .