How to capture non-integers in this Java program - java

How do I add a try-catch piece of code to stop someone from entering chars or, as a matter of fact, anything other than an int from 1 - 5?
boolean valid;
int option = 0;
do {
Scanner in = new Scanner(System.in); // need try catch
menu();
System.out.println("\n");
option = in.nextInt();
valid = option > 0 && option < 6; // try / catch needed around here?
} while(!valid); // stop chars and strings being entered
// I want to stop the user entering anything other than an int 1-5

if you need that number to check which option the user entered you dont need to do that. all you have to do is change the option variable from int to String and your if statements from
if(option==1) to if(option.equals("1"))
if you are going to need real ints for real mathematical equations then Sheetals answer will be more appropriate, but for a menu input, Strings are just fine.
dont forget that you can have String comparison with that contain numbers
"1"<"2" is true

Use string to enter the choice and then parse it using Integer.parseInt() function.
Scanner in = new Scanner(System.in);
String choice = in.next();
try{
int intChoice = Integer.parseInt(choice);
if(choice > 5){
throw new Exception("Can't be more than 5");
}
}catch(Exception e){
System.out.println(e.printStackTrace);
}

Why not read the token as a string and use Integer.parseInt(), ignoring tokens that cannot be parsed as an integer. If not then handle it

Related

Is there another way to use hasNextInt() in Java without putting everything in the if-statement?

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

How to compare a variable to see if it's the right class type?

I've been learning Java from scratch again since 2 years of rust, and I was playing around with a simple random generator code. My issue here is that when the user is asked what he wants as his highest die roll, it must be a number (int) class type.
I was trying to create an if statement and compare a variable to its class, rather than letting my IDE stop and show me an error message in a case the user typed letters.
Here is my code (It's the simplest code ever but it's safe to say that I'm new and motivating myself to learn Java again.) :
package firstguy;
import java.util.Random;
import java.util.Scanner;
public class randomnum {
public static void main(String[] args){
Random dice = new Random();
Scanner userin = new Scanner(System.in);
int number;
int highnum;
System.out.println("What's the highest roll you want? \n");
highnum = userin.nextInt();
for(int counter=1; counter<= highnum; counter++){
number= 1 + dice.nextInt(highnum);
System.out.println("This is the number " + number);
}
}
}
I want to be able to compare highnum, here to see if it stays as the class type int and not a letter. In case a letter or a character is typed, a message should be displayed or the question should be repeated. I've been trying to look for this problem but I keep getting results of comparing two variables of the same class type.
Is there no way to compare a variable to a class type?
Primitive types of Java do not have a class. Their wrapper types do, but your code does not use them.
What you are trying to do is to check end-user input for presence of character combinations that represent an integer vs. everything else. This is relatively easy to do, because Scanner provides methods hasNext... for various data types. You can use hasNextInt() in a loop, discarding the unwanted input, like this:
System.out.println("What's the highest roll you want? \n");
while (!userin.hasNextInt()) {
System.out.println("Please enter an integer.");
userin.nextLine();
}
// Since we reached this point, userin.hasNextInt() has returned true.
// We are ready to read an integer from the scanner:
highnum = userin.nextInt();
nextInt() (or most other nextXYZ methods, for that matter), throw an InputMismatchException if they encounter input that doesn't match their call (e.g., a letter in a nextInt call). So one option would be to simply catch it:
int highnum;
try {
highnum = userin.nextInt();
} catch (InputMismatchException e) {
System.out.println ("Wrong input encountered");
}
What you're looking for is not a way to "compare a variable to a class type", but rather to check a String to see if it has the right format. If you want to see if a String consists only of digits, the simplest way is using matches and a regular expression:
if (inputString.matches("\\d+")) {
... the input is valid
} else {
... complain
}
The regular expression here means "one or more digits". You could also use hasNextInt on a Scanner, or use nextInt on a Scanner and catch exceptions, or use Integer.parseInt(inputString) and catch exceptions, just to name a few.
try this:
boolean go = true;
System.out.println("What's the highest roll you want? \n");
while(go){
try{
highnum = userin.nextInt();
go = false;
catch(Exception e){
System.out.println("Please type in an integer: ");
highnum = userin.nextInt();
}
}

How to check if an input is an int and is between two values

I created a method to see if a value that the user entered is type int and is between liminf and limsup. It returns the value so I can use it as a menu option.
The string message tells the user to enter something, and the error tells the user to use a number between limunf and limsup.
My problem is that, for example, if the user enters the number 10 and the liminf is 7 and limsup e 9, it runs like the number 10 was between limsup and liminf.
public static int readInput(String message, String error, int liminf, int limsup, Scanner rd){
int option = 0;
do {
option = rd.nextInt();
System.out.println(message);
while (!rd.hasNextInt()) {
System.out.println("Please enter the option");
rd.nextLine();
}
option = rd.nextInt();
canal.nextLine();
} while (option > limsup || option < liminf);
return option;
}
When you're checking input, you need to do two things:
Check that the value is actually an integer
Check that the value is in the range
For checking if a value is an integer, you can use one of two approaches. Use hasNextInt on your Scanner, or use Integer.parseInt and catch NumberFormatExceptions. You said in your comments you can't use the second one, so we'll use the first one.
You always have to call hasNextInt before you you call nextInt, so you can do it like this:
int option = 0;
System.out.println(message);
System.out.println("Please enter the option");
while (!rd.hasNextInt()) {
rd.nextLine(); // Clears the invalid input
System.out.println("Please enter the option");
}
option = rd.nextInt();
This will loop until the user enters an int, then it will get that int. Note that not calling hasNextInt before calling nextInt will cause an error, which will happen in your current code if you try to enter a non-number.
Next, you need to do the bounds checking. You want it to be between limsup and liminf, where limsup > liminf, if I'm not mistaken. We need to determine the condition that will allow this.
Between is achieved by using greater than the lower number and less than the higher number. In this case, that's option >= liminf && option <= limsup. We want to loop when it's not this, so we can just wrap the whole thing in !():
int option = 0;
do {
System.out.println(message);
System.out.println("Please enter the option");
while (!rd.hasNextInt()) {
rd.nextLine(); // Clears the invalid input
System.out.println("Please enter the option");
}
option = rd.nextInt();
} while (!(option >= liminf && option <= limsup));
return option;
I'll let you figure out how/where to print the error message, but this should get you started.
Worth noting:
hasNextInt, nextInt, nextLine, etc. will all wait for user input if you use Scanner rd = new Scanner(System.in);
Using nextLine is necessary to clean out the old input and force the user to enter new input
While De Morgan's laws are cool, the easiest way to invert a condition is just to wrap it in a !()
Change you condition in while like this :
while (option <= limsup && option >= liminf);
With your current condition, when you have option = 10 and limsup = 9 then your condition option > limsup will evaluate to true and as you are using || (OR opeartor ) even if the second condition evaluates to false the whole expression will evaluate to true.
Here is how you test if a string is an integer:
private static boolean isInteger( String s ){
try{
Integer.parseInt(s);
return true;
catch( Exception e ){
return false;
}
}
However, since you are using the nextInt() function this is not necessary as you will only get integer inputs this way anyways.
while ((option > limsup) || (option < liminf))
You can check that if the input is an integer or not with Integer.parseInt(input); something like :-
try {
String s = "a";
int i = Integer.parseInt(s);
return true;
}
catch(NumberFormatException nfe){return false;}
and change the condition like:-
while (option <= limsup && option >= liminf);
I beleive, its your readLine is making it to ignore the next token(10) itself as its reading the entire line while hasNextInt checks the single token. Try simple as below (use next and remove the extra rd.nextInt() as first statement in your loop):
do {
System.out.println(message);
while (!rd.hasNextInt()) {
System.out.println("Please enter the option");
rd.next();
}
//now the next token is int
option = rd.nextInt();
//flush the new line if any
rd.nextLine();
} while (option > limsup || option < liminf);
Your check in the while is wrong (option > limsup || option < liminf)
Look at option > limsup, 10 is bigger then 9 that is why you got this problem

How to insist that a users input is an int?

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

Converting a string input from user to a numeric (int) value.

I've been trying different methods for converting a user string input into an int I could compare and build an "if-then" statement. Every time I tried testing it, it just threw exception. Can anyone look at my Java code and help me find the way? I'm clueless about it (also a noob in programming). If I'm breaking any rules please let me know I'm new here. Thank you.
Anyway, here is the code:
System.out.println("Sorry couldn't find your user profile " + userName + ".");
System.out.println("Would you like to create a new user profile now? (Enter Y for yes), (Enter N for no and exit).");
try {
BufferedReader answer = new BufferedReader(new InputStreamReader(System.in));
String addNewUser = answer.readLine();
Character i = new Character(addNewUser.charAt(0));
String s = i.toString();
int answerInDecimal = Integer.parseInt(s);
System.out.println(answerInDecimal);
}
catch(Exception e) {
System.out.println("You've mistyped the answer.");
e.getMessage();
}
It seems like you are trying to convert the string (which should be a single character, Y or N) into its character value, and then retrieve the numerical representation of the character.
If you want to turn Y or N into their decimal representation, you have to perform a cast to int:
BufferedReader answer = new BufferedReader(new InputStreamReader(System.in));
String addNewUser = answer.readLine();
char i = addNewUser.charAt(0);
int integerChar = (int) i; //The important part
System.out.println(integerChar);
This will return the integer representation of the character that the user input. It may also be useful to call the String.toUpperCase() method in order to ensure that different inputs of Y/N or y/n do not give different values.
However, you could also do an if-else based upon the character itself, rather than converting it to an integer.
BufferedReader answer = new BufferedReader(new InputStreamReader(System.in));
String addNewUser = answer.readLine();
char i = addNewUser.toUpperCase().charAt(0);
if (i == 'Y') {
//Handle yes
} else if (i == 'N') {
//Handle no
} else {
System.out.println("You've mistyped the answer.");
}
I think you meant to ask them to Enter 0 for yes and 1 for No ? Maybe?
You're asking the user to type Y or N and then you're trying to parse that to an integer. That will always throw an exception.
EDIT -- As others have pointed out, if you want to continue to use Y or N, you should do something along the lines of
String addNewUser = answer.readLine();
if ( addNewUser.toLowerCase().startsWith("y") ) {
// Create new profile
}
parseInt is just for converting text numbers into integers: everything else gets a NumberFormatException.
If you want the decimal ASCII value of a character, just cast it to an int.
Use if (addNewUser.startsWith("Y") || addNewUser.startsWith("y")) { instead.
Or (as Mark pointed) if (addNewUser.toLowerCase().startsWith("y")) {.
BTW maybe look at Apache Commons CLI?
You cannot convert String to int, unless you know the String contains a valid integer.
Firstly, using the Scanner class for input is better, since its faster
and you don't need to get into the hassle of using streams, if you're
a beginner. This is how Scanner will be used to take input:
import java.util.Scanner; // this is where the Scanner class resides
...
Scanner sc = new Scanner(System.in); // "System.in" is the stream, you could also pass a String, or a File object to take input from
System.out.println("Would you like to ... Enter 'Y' or 'N':");
String input = sc.next();
input = input.toUpperCase();
char choice = sc.charAt(0);
if(choice == 'Y')
{ } // do something
else if(choice == 'N')
{ } // do something
else
System.err.println("Wrong choice!");
This code could also be shortened to one line (however you won't be
able to check a third "wrong choice" condition):
if ( new Scanner(System.in).next().toUpperCase().charAt(0) == 'Y')
{ } // do something
else // for 'N'
{ } // do something
Secondly, char to int conversion just requires an explicit type
cast:
char ch = 'A';
int i = (int)ch; // explicit type casting, 'i' is now 65 (ascii code of 'A')
Thirdly, even if you take input from a buffered input stream, you
will take input in a String. So extracting the first character from
the string and checking it, simply requires a call to the charAt()
function with 0 as a parameter. It returns a character, which can
then be compared to a single character in single quotes like this:
String s = in.readLine();
if(s.charAt(0) == 'Y') { } // do something
Fourthly, its a very bad idea to put the whole program in a try
block and catch Exception at the end. An IOException can be
thrown by the readline() function, and parseInt() could throw a
NumberFormatException, so you won't be able to handle the 2
exceptions separately. In this question, the code is small enough for
this to be ignored, but in practice, there will be many functions
that can throw exceptions, hence it becomes easy to lose track of exactly which function threw what exception and proper exception handling becomes quite difficult.

Categories