I need to check a user is inputting a numeric value in java. I've been trying to use the hasNextDouble but am getting weird errors using the hasNextDouble method and am not certain this is the way to perform this check.
Please note I cannot use while loops or any other advanced method except if.
import java.util.Scanner;
import java.lang.Math;
public class CentimeterInch
{
public static void main (String [] args)
{
final int MAX=100, feet=12, meter=100;
final double inch=2.54;
Scanner scan = new Scanner (System.in);
System.out.println ("This program converts distances. ");
System.out.println ("Enter distance and unit (e.g. 37 1 or 100 2):");
double distance=scan.nextDouble();
if (!scan.hasNextDouble())
{
System.out.println ("please enter a numeric value");
distance=scan.nextDouble();
}
int unitType = scan.nextInt();
if (distance<0)
{
System.out.println ("Please enter a non negative distance");
}
....
I fixed the typo but its still not functioning, when I input for example "a" it crashes. To me it also doesnt make sense to call hasNextDouble after placing the value in the 'double distance' variable but I didn't find any other way yet.
I only have 1 double variable to check, the 'int' does not need validation.
EDIT:
I advance a bit. Now it displays the error before crashing. How do I make it not crash but take the variable again?
if(!scan.hasNextDouble())
System.out.println ("please enter a numeric value");
distance=scan.nextDouble();
Thank you!
Typos aside, you're invoking hasNextDouble after consuming nextDouble.
The easiest way to fetch both in one line is to:
if (scan.hasNextDouble()) {
// TODO something
double foo = scan.nextDouble(); // this consumes the first double
}
else { // TODO exit with error }
if (scan.hasNextDouble()) {
// TODO something else
double bar = scan.nextDouble(); // this consumes the second double
}
else { // TODO exit with error }
If you want it in two gos (i.e. user presses enter twice) you can consume scan.next() twice and use Double.parseDouble on both String, while catching a NumberFormatException for format errors.
It should be scan.hasNextDouble() with emphasis on Double.
Related
I'm writing a program that culculates tip and total from bill and tip rate.
public void takeUserInput() {
Scanner sc = new Scanner(System.in);
double billAmount;
int tipRate;
try {
System.out.print("What is the bill? ");
billAmount = sc.nextDouble();
System.out.print("What is the tip percentage? ");
tipRate = sc.nextInt();
tc.calculate(billAmount, tipRate);
} catch (InputMismatchException e1) {
String errorMessage = "Please enter a valid number for the ";
// errorMessage += billAmount or
// errorMessage += tipRate ?
}
I'm looking for a way to find out which variable throws InputMismatchException, so I can add which variable name into variable errorMessage and print to the screen.
There are various simple ways to get there:
Call hasNextXxx() prior calling nextXxx().
If you go for one try/catch block per input, it is very clear within your catch block which variable caused the problem (you could then call a generic method with a specific error message to avoid code duplication)
You could use reference types for your variables; if you use Double / Integer instead of double / int ... you could check which of the two variables is still null
You put in a little boolean variable, like billAmountIsValid. Initially that variable is false, you turn it to true after the call to nextDouble(). Then you can easily check in your try block whether you got a valid billAmount.
After some more thinking: you really want a combination of 1 + 2: you see; when the users enters a correct billAmount; why would you want to forget about that value when the second value gives a bad second value? No - you should be looping for each variable, until you receive a valid input. And only then you start asking for the next value!
The variable isn't throwing the exception, the evaluation of the right hand side of the variable assignment is, and so there is no information in the exception to say which variable it was about to assign that to had it succeeded.
What you could consider instead is a new method that encompasses the prompting messages and retries:
billAmount = doubleFromUser(sc, "What is the bill? ", "bill");
Where doubleFromUser is:
static double doubleFromUser(Scanner sc, String prompt, String description){
while(true) { //until there is a successful input
try {
System.out.print(prompt); //move to before the loop if you do not want this repeated
return sc.nextDouble();
} catch (InputMismatchException e1) {
System.out.println("Please enter a valid number for the " + description);
}
}
}
You will need a different one for int and double, but if you have more prompts, you will save in the long run.
My objective is to make sure the user inputs an int. Else, exit the program. Then I do some coding that requires that int.
Code Snippet :
Scanner input = new Scanner(System.in);
if (input.hasNextInt()) {
//check if user enters an int
int userinput = input.nextInt();
// assign that int input to variable userinput
// over 100+ lines of code using nextInt var "userinput"
} else {
System.exit(1);
// user did not enter an int
}
Is there a better way to check for whether a user has entered an int and then use that int that doesn't require my entire program to be coded into that if-statement (because nextInt's scope is limited to that if-statement)?
It feels messy to me to put everything into one if-statement.
I wouldn't be allowed to use separate objects/classes since it's early in the semester for my class. This all goes in the main method, and I'm just using simple if-statements/scanner inputs.
Thanks
Definitely! Just negate the if statement and early exit:
Scanner input = new Scanner(System.in);
if (!input.hasNextInt()) {
System.exit(1);
}
// "else"
doMagicalThings(input.nextInt());
Oh, I guess also to note: replace the 100 lines of code with a method call and break it up a bit. That'd be good to do in addition to the above.
Here is a simple example of using hasNextInt () to validate a positive integer input
Scanner input = new Scanner(System.in);
int number;
do {
System.out.println("Input Number ");
while (!input.hasNextInt()) {
System.out.println(" not a number!");
input.next();
}
number = input.nextInt();
} while (number <= 0);
System.out.println("Númber válid " + number);
I am new to java and doing an assignment.
I have to request 3 inputs from the user and I have validation.
If I do it with only one instance of the scanner I get all messed up.
If I use three instances with a bit of workaround my code works.
Only I guess this is not best practice.
I have been reading a bit the manual regarding the scanner, but cannot understand the problem
Thanks
enter code here
Scanner input=new Scanner(System.in);
Scanner input2=new Scanner(System.in);
int input_integer=0;
double input_double=0.0;
String input_string="";
double value=0;
System.out.print("\n Please enter a number: ");
while(!input.hasNextInt()){
System.out.println("***** Error: the char inserted is not a number! *****");
String input_wrong=input.next();
System.out.print("\n Please enter a number: ");
}
input_integer=input.nextInt();
System.out.print("\n Please enter a double: ");
while(!input.hasNextDouble()){
System.out.println("***** Error: the char inserted is not a double! *****");
String input_wrong=input.next();
System.out.print("\n Please enter an double: ");
}
input_double=input.nextDouble();
System.out.print("\nPlease enter a string: ");
input_string=input.nextLine();
So I had two create 3 scanner instances and also to use a string to assign the wrong input in the while cycle to the able to prompt again.
Any suggestion?
I am sure there is a better way but I would try to understand..
Thanks!
I'm not exactly sure I understand what problem you're having, but scanner has some strange behaviors which are not immediately obvious. For instance, if you type "1234bubble" then press enter, then nextInt() will return 1234 and the next nextLine() will say "bubble". That is usually not desired behavior for inputs like this because "1234bubble" is not an integer and should have failed when the user pressed enter.
For that reason, I typically only use the function nextLine(). Then, I just process the data manually using functions like Integer.parseInt(..). That way, I can guarantee that I'm processing the whole line in a clear and obvious manner, unlike other techniques which create confusing code.
Here's how I would have written your program:
import java.io.IOException;
import java.util.Random;
import java.util.Scanner;
public class Main
{
static Random rand = new Random();
public static void main(String[] args) throws IOException
{
Scanner input = new Scanner(System.in);
int input_integer = 0;
double input_double = 0.0;
String input_string = "";
double value = 0;
while (true)
{
System.out.print("Please enter an integer: ");
// Get the entire next line of text
String text = input.nextLine();
try
{
// Try to turn the line into an integer
input_integer = Integer.parseInt(text);
// Turning it into an int succeeded!
// Leave the while loop
break;
} catch (NumberFormatException e)
{
// Turning it into an int failed.
System.out.println("***** Error: the text inserted is not an integer! *****");
}
}
while (true)
{
System.out.print("Please enter a double: ");
// Get the entire next line of text
String text = input.nextLine();
try
{
// Try to turn the line into a double
input_double = Double.parseDouble(text);
// Turning it into an double succeeded!
// Leave the while loop
break;
} catch (NumberFormatException e)
{
// Turning it into an double failed.
System.out.println("***** Error: the text inserted is not a double! *****");
}
}
System.out.print("Please enter a string: ");
input_string = input.nextLine();
// This is done automatically when the program stops, but it's
// a good habit to get into for longer running programs.
input.close();
}
}
This question already has answers here:
How to test if a double is an integer
(18 answers)
Closed 7 years ago.
I'm writing a program in which I need to take input from the keyboard. I need to take a number in, yet I'm not sure if it's an int or a double. Here's the code that I have (for that specific part):
import java.io.*;
import java.util.*;
//...
Scanner input = new Scanner(System.in);
int choice = input.nextInt();
I know I can get a String and do parseInt() or parseDouble(), but I don't know which one it'll be.
Well, ints are also doubles so if you assume that everything is a double you will be OK with your logic. Like this:
import java.io.*;
import java.util.*;
Scanner input = new Scanner(System.in);
double choice = input.nextDouble();
It only get complex if you needed the input to be an integer for whatever reason. And then, parseInt() to test for int would be just fine.
Just use a double no matter what it is. There is no noticeable loss on using a double for integral values.
Scanner input = new Scanner(System.in);
double choice = input.nextDouble();
Then, if you need to know whether you've gotten a double or not, you can check it using Math.floor:
if (choice == Math.floor(choice)) {
int choiceInt = (int) choice);
// treat it as an int
}
Don't mess with catching NumberFormatException, don't search the string for a period (which might not even be correct, for example if the input is 1e-3 it's a double (0.001) but doesn't have a period. Just parse it as a double and move on.
Also, don't forget that both nextInt() and nextDouble() do not capture the newline, so you need to capture it with a nextLine() after using them.
What I would do is get String input, and parse it as either a double or an integer.
String str = input.next();
int i = 0;
double d = 0d;
boolean isInt = false, isDouble = false;
try {
// If the below method call doesn't throw an exception, we know that it's a valid integer
i = Integer.parseInt(str);
isInt = true
}catch(NumberFormatException e){
try {
// It wasn't in the right format for an integer, so let's try parsing it as a double
d = Double.parseDouble(str);
isDouble = true;
}catch(NumberFormatException e){
// An error was thrown when parsing it as a double, so it's neither an int or double
System.out.println(str + " is neither an int or a double");
}
}
// isInt and isDouble now store whether or not the input was an int or a double
// Both will be false if it wasn't a valid int or double
This way, you can ensure that you don't lose integer precision by just parsing a double (doubles have a different range of possible values than integers), and you can handle the cases where neither a valid integer or double was entered.
If an exception is thrown by the code inside the try block, the code in the catch block is executed. In our case, if an exception is thrown by the parseInt() method, we execute the code in the catch block, where the second try-block is. If an exception os thrown by the parseDouble() method, then we execute the code inside the second catch-block, which prints an error message.
You could try using the floor function to check if it is a double. In case you don't know, the floor function basically cuts off any decimal numbers. So you can compare the number with and without the decimal. If they are the same, then the number can be treated as an integer, otherwise a double (assuming you don't need to worry about large numbers like longs).
String choice = input.nextLine();
if (Double.parseDouble(choice) == Math.floor(Double.parseDouble(choice)) {
//choice is an int
} else {
//choice is a double
}
Basic problem here.. I will start off by asking that you please not respond with any code, as that likely will only confuse me further (programming noob). I am looking for a clear explanation on how to solve this issue that I'm having.
I have a scanner that reads input from the user. The user is prompted to enter an int value between 1 to 150 (whole numbers only). I obtain the value as follows:
Scanner scan = new Scanner(System.in);
int input = scan.nextInt();
And continue on with my program, and everything works fine.
Unfortunately, the code isn't exactly bulletproof, since any input that is not an integer can break it (letters, symbols, etc).
How can I make the code more robust, where it would verify that only an int was entered?
These are the results I'm hoping for:
Lets say the input was:
23 -> valid
fx -> display an error message, ask the user for input again (a while loop would do..)
7w -> error, again
3.7 -> error
$$ -> error
etc
Scanner.hasNextInt() returns true if the next token is a number, returns false otherwise.
In this example, I call hasNextInt(). If it returns true, I go past the while and set the input; if it returns false, then I discard the input (scanner.next();) and repeat.
Scanner scan = new Scanner(System.in);
while(!scan.hasNextInt()) {
scan.next();
}
int input = scan.nextInt();
Here's a simple example with prompts and comments.
Scanner scan = new Scanner(System.in);
System.out.print("Enter an integer: "); // Initial prompt for input
// Repeat until next item is an integer
while (!scan.hasNextInt())
{
scan.next(); // Read and discard offending non-int input
System.out.print("Please enter an integer: "); // Re-prompt
}
// At this point in the code, the user has entered an integer
int input = scan.nextInt(); // Get the integer
// And now you can use the input variable.
Use scan.hasNextInt() to make sure the next input is an int.
I have written an example that ensures that the program will continue only if a number and not an invalid value is entered. Do not worry, I added the desired explanation.
The program asks the user to input a number. A loop ensures that the processing will not go on until a valid number is entered. Before that I have defined a variable "inputAccepted" that has false as default value. If he enters a number, the variable "inputAccepted" is set to true and the program leaves the loop. But if he enters something else than a number, an exception is thrown right in this moment, and the line that sets the variable "inputAccepted" to true will not be executed. Instead a message will be printed out that tells the user that his input is not valid. Since "inputAccepted" could not be set to true, the loop will do the same stuff again until the string can be converted to a number.
You can test the program here.
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
boolean inputAccepted = false;
while (!inputAccepted) {
try {
System.out.print("Please enter a number: ");
Integer.valueOf(input.nextLine());
inputAccepted = true;
} catch (NumberFormatException e) {
System.out.println("Not a valid number.");
}
}
System.out.println("Thank you!");
}
}
Just get "anything" and parse it:
Scanner scan = new Scanner(System.in);
Integer number = null;
while (number == null) {
try {
number = Integer.parseInt(scan.next());
} catch (NumberParseException e) {
System.out.println("bad input: " + input);
}
}
Without any code and just in English, I'd say there's two things you have to test or look out for. First that the input is an int, second that the int is within the correct range.
In terms of pseudocode, the first thing to do is make sure it's an int. Declaring an int named "input", I would put a try / catch block, where you try to scan in the user input as an int, with parseInt(). If the try part fails, you know it's not an int and can return an error message.
Then, now that you know that "input" is an int, you can test whether it is less than 1 or more than 150, and return an error message if so!
public class Sample {
/**
* author CLRZ
*/
public static void main(String[] args) {
int a; // variable
Scanner in = new Scanner(System.in); // scans your input
System.out.println("Enter your number's choice:");
int sem1 = in.nextInt(); // reads next integer
if (sem1 == 1) // conditioned if your choice number is equal to 1
System.out.println("Hello World1"); // output wil be Hello World
int b;
System.out.println("Enter your number's choice:");
int sem2 = in.nextInt();
if (sem2 == 2)
System.out.println("Hello World2");
int c;
System.out.println("Enter your number's choice:");
int sem3 = in.nextInt();
if (sem3 == 3)
System.out.println("Hello World3");
}
}