What is the best way to read number from console using scanner? - java

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

Related

Error handling in JAVA - Check correct input type

Not sure where i'm going wrong, please help. Trying to check if the user has only entered an integer. Error showing strInpit cannot be resolved to a variable.
import java.util.Scanner;
public class Salary{
public static void main(String[] args){
int num = 0;
String strIntput;
boolean valid = false;
// setup scanner
Scanner in = new Scanner(System.in);
// loop to check for valid input
while(valid == false){
//prompt user to enter
System.out.println("Enter your salary per year");
// grab input from keyboard
strInput = in.nextLine();
// try to convert String to int
try{
num = Integer.parseInt(strInput);
valid = true;
}
catch(NumberFormatException e){
System.out.println("Error - enter an integer value.");
}
}
System.out.println("your salary is " + num);
}
}
you have named the variable as String strIntput;
while declaring it..but you are using strInput everywhere else
so change String strIntput; TO String strInput;
There is another method which you can use:
#Scaner.nextInt(); It will get Integer value from console or, in another case, will throw an exception

types cannot be converted when validating the users input for an integer

I am trying to validate a user's input and check if the inputted number is an integer. Id like to throw them an error message if the number isn't an integer. I am getting stuck on the line Integer.parseInt(number); Any suggestions would be very appreciated.
import java.util.Scanner;
public class Sums {
public static int number;
public static void main(String[] args) {
int evenSum, oddSum = 0;
int posInt;
Scanner input = new Scanner(System.in);
System.out.println("Enter a postitive integer: ");
int number = input.nextInt();
try {
Integer.parseInt(number);
System.out.println("Value entered is " + number);
} catch (NumberFormatException e) {
System.out.println(number + " is not an integer.");
}
}
}
I have changed the int number = input.nextInt(); to String number = input.next(); and it works.
The issue here is that when you call Integer.parseInt(number) you are trying to parse the variable number which is an int and not a String. This means that you are doing the error checking on a conversion from an int to an Integer and not a String to an Integer.
To fix this, input a string instead of a number, then perform the conversion on the string, not the number.
...
public static void main(String[] args) {
int myNumber;
Scanner input = new Scanner(System.in);
System.out.println("Enter a postitive integer: ");
String numberString = input.nextLine();
try {
myNumber = Integer.parseInt(number);
System.out.println("Value entered is " + myNumber);
// do what you want with the number
} catch (NumberFormatException e) {
System.out.println(numberString + " is not an integer.");
}
}
...
You don't need explicitly to convert your number to an integer, Scanner.nextInt() already does that for you, i.e. Scanner.nextInt() scans the next token of the input as an int. So just remove the line "int number = input.nextInt();" from your code. In general, Integer.parseInt() is preferable when you want to convert a String representation of an Integer value as a signed decimal integer. For instance, if you would have used Scanner.nextLine() instead of Scanner.nextInt(), then it makes more sense to convert it to a signed decimal integer if you want to perform subsequent operations using that integer value.
int number = input.nextInt();
The variable number is already an int, that is why you can not hand it over to the method. The method requires a String.
If you want to use the method like you did, you should use
input.next()
as argument because it returns the input as String and initialize number within the try block, e.g.
public static void main(String[] args) {
int evenSum, oddSum = 0;
int posInt;
System.out.println("Enter a postitive integer: ");
Scanner input = new Scanner(System.in);
try {
number = Integer.parseInt(input.next());
System.out.println("Value entered is " + number);
} catch (NumberFormatException e) {
System.out.println("Not an integer.");
}
}
Bug here is int number = input.nextInt();
When you want to convert a String to a primitive datatype we use class.parseXXX(String)
You see I have written String in the function .parseXXX(String) Cause it takes String as a parameter and nothing else
So lets read your code
Integer.parseInt(number);
Here its .parseXXX(int) and clearly its not matching .parseXXX(String)
So in order to give String as parameter, you have accept String as input from user.
Replace this int number = input.nextInt(); with String number = input.next();
So now below code is valid cause its in .parseXXX(String)
Integer.parseInt(number);
Changed code:
int evenSum, oddSum = 0;
int posInt;
Scanner input = new Scanner(System.in);
System.out.println("Enter a postitive integer: ");
String number = input.next(); // <-- Changed
try {
Integer.parseInt(number);
System.out.println("Value entered is " + number);
} catch (NumberFormatException e) {
System.out.println(number + " is not an integer.");
}

try catch in a do while loop

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

Validating multiple Inputs with Scanner

I'm trying to create some input validation for incorrect input in my program.
The program is supposed to read the user input as a double but it must display a message that input is not a number if the user types a letter instead of a number.
To do this, I use input.hasNextDouble with an if statement. The else, prints the message that x is not a number. However, my problem lies with the second number that the user inputs. Let's say that the user enters "5 f" The hasNextDouble interprets the double and then executes the code under the if statement, but the input is still incorrect because of the "f".
In short, I need a way for the first input (5) to be removed from the buffer so the second input can be interpreted.
Any help is appreciated!
here is some sample code:
if ( keyboard.hasNextDouble() ) {
double i = keyboard.nextDouble();
double j = keyboard.nextDouble();
double answer = (j+i );
System.out.println(answer);
}
else {
String a = keyboard.next();
String b = keyboard.next();
System.out.println( a + "is not a number");
double i,j, answer;
try{
i = keyboard.nextDouble();
j = keyboard.nextDouble();
answer = i+j;
} catch( InputMismatchException e ) {
// One of the inputs was not a double
System.out.println("Incorrect format");
}
otherwise if you absolutely need to print out which was incorrect, I would just do the if-then you have twice.
double i=null, j=null, answer;
// get input for i
if ( keyboard.hasNextDouble() ) {
i = keyboard.nextDouble();
}else{
System.out.println( keyboard.next() + " is not a double");
}
// get input for j
if ( keyboard.hasNextDouble() ) {
j = keyboard.nextDouble();
}else{
System.out.println( keyboard.next() + " is not a double");
}
// if both i and j received inputs
if( i != null && j != null )
answer = i + j;
else
System.out.println("Malformed input");
You need something like following.
double tryReadDouble(Scanner keyboard) throws NumberFormatException {
if (keyboard.hasNextDouble()) {
return keyboard.nextDouble();
} else {
throw new NumberFormatException(keyboard.next());
}
}
And
try {
double i = tryReadDouble(keyboard);
double j = tryReadDouble(keyboard);
double answer = (j + i);
System.out.println(answer);
} catch (NumberFormatException ex) {
System.out.println(ex.getMessage() + "is not a number");
}
Hope this helps.
You can create helper method which will ask user for valid input, until it gets one, or until some limit of tries will be exceeded. Such method can look like this:
public static double getDouble(Scanner sc, int maxTries) {
int counter = maxTries;
while (counter-- > 0) {// you can also use `while(true)` if you
// don't want to limit numbers of tries
System.out.print("Please write number: ");
if (sc.hasNextDouble()) {
return sc.nextDouble();
} else {
String value = sc.next(); //consume invalid number
System.out.printf(
"%s is not a valid number (you have %d tries left).%n",
value, counter);
}
}
throw new NumberFormatException("Used didn't provide valid float in "
+ maxTries + " turns.");
}
then you can use this method like
Scanner keyboard = new Scanner(System.in);
double i = getDouble(keyboard, 3);
double j = getDouble(keyboard, 3);
double answer = (j + i);
System.out.println(answer);

How to resolve NumberFormatException: Empty string?

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.

Categories

Resources