Testing for blank input using Scanner class during input validation - java

I need to ask the user to enter a positive non-zero integer from the console that I will use as a product number in my program.
If I enter any non-integer value, the program correctly enters the while loop.
If I enter a 0 or a negative integer, the program correctly throws the exception (which I catch and handle elsewhere).
When I just press the enter key (or end of line character) it seems that the program just puts the console to another line. I want it to enter the while loop to display the error message. I think the cause is that hasNextInt() will wait until the token is a non end of line character input.
private static void validateProductNumber() throws InvalidProductNumberException {
Scanner keyboard = new Scanner(System.in);
int number;
while(!keyboard.hasNextInt()) {
System.out.println("Number must be an integer. Try again. ");
System.out.println("Enter a new number: ");
keyboard.next();
}
number = keyboard.nextInt();
if (number <= 0)
throw new InvalidProductNumberException();
newNumber = number;
}
Is there another way I can implement my input validation with Scanner class so that it works correctly for all situations?

You can change your loop as follows:
while(true) {
try {
System.out.println("Enter a new number: ");
//read the line and parse it
number = Integer.parseInt(keyboard.nextLine());
break; //break the loop if the input is a valid integer
} catch(Exception ex) {
//print the error message if the input is incorrect
System.out.println("Number must be an integer. Try again. ");
}
}
if (number <= 0)
//...

Related

Java: show different results depending on User Console Input without try...catch statement

I try to write a programm in Java that gets user input using Scanner Class. The user has to enter any positive integer number. Depending on user actions, the results should be as follows:
The user has entered not an integer number -> the programm prints the message
Oops! You entered something different, but not an integer number, try again
The user has entered not a positive integer number -> the programm prints the message
You entered not a positive integer number, try again
The user has entered a positive integer number -> the programm prints the number
User's positive integer number - ...
I have written some code using loop and Scanner class
public static void main(String[] args) {
int userIntNum;
boolean isUserInputCorrect;
#SuppressWarnings("resource")
Scanner sc = new Scanner(System.in);
userIntNum = 0;
System.out.println("Please, enter a positive integer number");
isUserInputCorrect = (sc.hasNextInt() && (userIntNum > 0));
// double console input for correct integer number
while (isUserInputCorrect == false) {
if (!sc.hasNextInt()) {
System.out.println("Oops! You entered something different, but not an integer number, try again");
sc.nextLine();
} else if (sc.nextInt() <= 0) {
System.out.println("You entered not a positive integer number, try again");
sc.nextLine();
} else {
break;
}
}
userIntNum = sc.nextInt();
System.out.println("User's positive integer number - " + userIntNum);
When I put in the console a positive integer number (the correct input), the programm, for some reason, asks me to enter this number twice.
Moreover, if I put first an integer number and then any non-positive number separated by space, it will print this incorrect number. And if I put first an integer number and then not an integer number separated by space, it will throw an exception.
Why does it happen and how can I fix these errors?
First, I would eliminate isUserInputCorrect. You are trying to do too much with it, instead I would loop while userIntNum is less than or equal to zero. Also, try and limit variable scope. Something like,
Scanner sc = new Scanner(System.in);
int userIntNum = -1;
System.out.println("Please, enter a positive integer number");
// double console input for correct integer number
while (userIntNum <= 0) {
if (sc.hasNextInt()) {
userIntNum = sc.nextInt();
} else {
System.out.println("Oops! You entered something different, "
+ "but not an integer number, try again");
sc.nextLine();
}
if (userIntNum <= 0) {
System.out.println("You entered not a positive integer number, try again");
}
}
System.out.println("User's positive integer number - " + userIntNum);
Expanding on Elliott's answer above, I wanted to provide an alternative solution that addresses your following point:
Moreover, if I put first an integer number and then any non-positive
number separated by space, it will print this incorrect number. And if
I put first an integer number and then not an integer number separated
by space, it will throw an exception.
The Scanner class will read tokens individually in a temporal fashion. If you look at the nextInt() function you will see it that throws InputMismatchException which you can explicitly catch.
Additionally, take a look at the Java modulus operator. Since you are explicitly looking for even values, the modulus operator is extremely valuable here.
public static void main(String[] args) {
int userIntNum = 0;
boolean isUserInputCorrect = false;
#SuppressWarnings("resource")
Scanner sc = new Scanner(System.in);
do {
System.out.println("Please, enter a positive integer number");
try {
userIntNum = sc.nextInt();
isUserInputCorrect = (userIntNum > 0 && userIntNum % 2 == 0);
} catch (InputMismatchException ex) {
System.out.println("Invalid input: please enter an integer value");
sc.next();
}
} while(!isUserInputCorrect);
System.out.println("User's positive integer number - " + userIntNum);
}

Endless loop - scanner.hasNextInt() inside a while loop

The questions are in the comments of the code, sorry for that, I thought it's neater, as the flow is important, I guess...
import java.util.Scanner;
public class ReadingUserInput {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Please, enter 10 numbers, for example, from 1 to 100!");
int number = 0;
int total = 0;
int counter = 0;
while (counter < 10) {
System.out.println("Enter number #" + (counter + 1));
boolean hasNextInt = scanner.hasNextInt(); // here we open the prompt for user to enter the value/s*
// internally, we are ready to check if the input is going to be int
// user types the value/s and clicks enter
// let's presume, he/she typed '3'
// internally, user's input is like that (if Windows**) - '3\n'
// because when user presses Enter - \n is added to what he/she typed
if (hasNextInt) { // the app checks, ant it's int, that is, it's OK (true)
number = scanner.nextInt(); //here the application grabs user's input
//but, internally, it grabs only '3', because 'nextInt()' grabs only ints
// and doesn't "care" about the new feed/line - \n - character
// so, '\n' is left in Scanner's buffer!
counter++;
total += number;
} else {
System.out.println("Invalid Input! Try again!");
}
//scanner.nextLine(); // let's presume, this commented line, on the left of this line of comment, is absent in our code
// the flow of our code goes to boolean hasNextInt = scanner.hasNextInt();
// and again internally, we are ready to check if the input is going to be int
// and again the user is prompted (by a blinking cursor) to type his/her input
// and at this moment user types either a numeric again or a non-numeric character (a letter/letters)
// let's presume he/she is typing '4'
// and again, internally, user's input is actually like that (if Windows**) - '4\n'
// but scanner.hasNextInt() says 'OK', for the int is there! and it doesn't care about '\n'
//
// Now, let's presume that user (this time or next time) types 'a'
// Do we actually have 'a\n' ???
// and this time scanner.hasNextInt() says 'Alarm' - 'false'
// thus the input doesn't go to number = scanner.nextInt();
// So, does it mean that 'a\n' (or 'a') remains in Scanner's buffer???
// and it (scanner.hasNextInt()) kicks us to 'else'
// and we have an endless loop:
//Invalid Input! Try again!
//Enter number #...
//Invalid Input! Try again!
//Enter number #...
//Invalid Input! Try again!
//Enter number #...
//Invalid Input! Try again!
//Enter number #...
//Invalid Input! Try again!
//Enter number #...
//Invalid Input! Try again!
//Enter number #...
//Invalid Input! Try again!
//Enter number #...
//Why?
// Is there still 'a' (or 'a\n') and scanner.hasNextInt() throws the flow to 'else' endlessly,
// because "The scanner does not advance past any input"* ???
//
// or: there's only '\n', and again its not int, and we result in endless loop ???
// And finally, is that a different case? https://www.youtube.com/watch?v=_xqzmDyLWvs
// And PS: Is there anything wrong in my description in the comments?
// So what do we 'consume' by scanner.nextLine(); ???
}
scanner.close();
System.out.println("Thank you, your total is " + total);
}
}
// *This is from Oracle :(https://docs.oracle.com/javase/6/docs/api/java/util/Scanner.html#hasNextInt%28%29)
"hasNextInt
public boolean 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."
// **https://knowledge.ni.com/KnowledgeArticleDetails?id=kA00Z0000019KZDSA2
Create another scanner object instead and forget about what is left in the internal buffer.
public class ReadingUserInput {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Please, enter 10 numbers, for example, from 1 to 100!");
int number = 0;
int total = 0;
int counter = 0;
while (counter < 10) {
System.out.println("Enter number #" + (counter + 1));
boolean hasNextInt = scanner.hasNextInt();
if (hasNextInt) {
number = scanner.nextInt();
counter++;
total += number;
} else {
System.out.println("Invalid Input! Try again!");
scanner = new Scanner(System.in);
}
}
scanner.close();
System.out.println("Thank you, your total is " + total);
}
}

using string to break out of loop in java

I simply would like to break out of a while true loop if the user enters in "STOP" into the scanner. Currently my scanner only takes in integers and I believe this is where the problem lies. If I try to type in "STOP" I get many errors saying "exception in thread main". Here is a snippet of my code:
public class algorithm {
private Scanner input = new Scanner(System.in);
int n;
while (true){
System.out.println("Eneter a number to check if it is odd or even, then hit enter: ");
System.out.println("Type 'STOP' to end the program");
n = input.nextInt();
String strN = String.valueOf(n); //convert integer to string
if (new String(strN).equals("STOP")){ //if string is STOP, breaks
System.out.println("Thanks for using my program");
break;
}
if (n % 2 == 0){
System.out.println(n+" is even");
continue;
}
else{
System.out.println(n+" is odd");
continue;
I know I am missing some closing curly braces but rest assured they are all there in my actual code. Thanks.
Here is the error I am getting:
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:864)
at java.util.Scanner.next(Scanner.java:1485)
at java.util.Scanner.nextInt(Scanner.java:2117)
at java.util.Scanner.nextInt(Scanner.java:2076)
at OddOrEven.algorithm.checker(algorithm.java:13)
at OddOrEven.main.main(main.java:7)
You've already identified the problem yourself - your Scanner reads only integers:
int n;
...
n = input.nextInt();
so it's impossible for the variable n (an int) to contain the string "STOP" (and your Scanner throws an exception anyway when you call nextInt() but it encounters a string, such as "STOP", that it cannot convert to an int).
To do this, you need to read strings from the input (probably using Scanner.nextLine()), check whether they are "STOP", and if not, only then attempt to convert them to ints using something like:
int n = Integer.parseInt(mystring)
To handle garbage input (neither STOP nor an integer), wrap the parseInt line in a try-catch block so that you can detect when the input is garbage by catching the Exception
try {
int i = Integer.parseInt(mystring);
// do something with the int
}
catch (NumberFormatException e) {
// display warning message to the user instead
}
See also this related question.
The most simple way is probably to use input.next() instead of input.nextInt(). Using input.next() will read input in as a String, then you can check if the input is equal to "QUIT", if it is not you can use Integer.parseInt to parse the Integer from the read string
Something like below, should work out.
NOTE: havent tested compile errors, just wrote it out(but you get a gist)
public Scanner input = new Scanner(System.in);
int n;
while (true){
System.out.println("Eneter a number to check if it is odd or even, then hit enter: ");
System.out.println("Type 'STOP' to end the program");
n = input.next();
Integer input;
// String strN = String.valueOf(n); //convert integer to string
if (strN.equals("STOP")){ //if string is STOP, breaks
System.out.println("Thanks for using my program");
break;
}
else{
try{
input= Integer.parseInt(strN);
}
catch(Exception e)
{
System.out.println("Please enter a number");
}
}
if (input % 2 == 0){
System.out.println(n+" is even");
continue;
}
else{
System.out.println(n+" is odd");
continue;
}

How to continue loop inside of Try Catch for Guessing game

So my problem is that i don't know how to continue my program when i do the try and catch for input errors. I tried using the "continue;" code after my catch statement but that just loops my program uncontrollably. I need the program to start where it left off after the user does an incorrect input. Any help would be appreciated. Note that this was an assignment BUT I'm going above and beyond by handling junk in my code.
//Import library
import java.io.*;
import java.util.*;
//File name
public class GuessingGame
{
//Main throws Input and output error
public static void main (String [] args) throws IOException
{
//inputs for users
Scanner in = new Scanner (System.in);
Scanner i = new Scanner (System.in);
//variables for the loop, random number, character and counter
int guess = 0;
int rnd;
char decision;
boolean loop = false;
//random number generator
Random random = new Random();
rnd = random.nextInt(100) + 1;
//loops the guess and input
while (!loop){
try{
System.out.println(rnd);
//prompt the user
System.out.println(" Please guess a number between 1-100. Press 0 to exit.");
int num = in.nextInt();
//if statements
if (num==0)
{
//when user types '0' it ends the program
System.exit(0);
System.out.println("You gave up!.... Reseting program...");
}
else if (num>rnd)
{
//prints too big, adds to counter 'guess'
System.out.println("The number is too big!");
guess++;
}
else if (num<rnd)
{
//prints too small, adds to counter 'guess'
System.out.println("The number is too small!");
guess++;
}
else
{
//prints correct, adds to counter, dsiplays # of guesses and ends loop
System.out.println("You guessed the number right!!");
guess++;
System.out.print(" # of guesses: " + guess);
//Note**: i could've just put 'break;' but the compiler would'nt read the rest of the code below
loop = true;
//loops the case untill correct input is chosen either 'Y' or 'N'
while(true){
//prompt the user if they want to play again
System.out.println(" Would you like to play again? Y/N?");
decision = i.nextLine().charAt(0);
switch (decision) {
case 'Y':
case 'y':
//calls main, basically restarts the game
GuessingGame.main(args);
break;
case 'N':
case 'n':
System.out.println("Bye!");
//exits the program completely
System.exit(0);
break;
default:
//if incorrect input, this prints
System.out.println("Please enter a Yes or No <Y/N>");
}
}
}
}
//catches input errors
catch (Exception e){
System.out.println("Only numbers!!!");
//GuessingGame.main(args);
continue;
}
}
}
Try this move your catch up because you are only testing the input. Also add in.nextLine() in your catch to eat up the character that is left behind.
while (!loop){
int num;
try{
System.out.println(rnd);
//prompt the user
System.out.println(" Please guess a number between 1-100. Press 0 to exit.");
num = in.nextInt();
}
catch (Exception e){
System.out.println("Only numbers!!!");
//GuessingGame.main(args);
in.nextLine();
continue;
}
Scanner by default splits the standard input by spaces and keeps an index of how many substrings have been parsed. The specific method you call (.nextWhatever) will attempt to parse the next string in line to its expected type and will only increase the index if it's successful; if there's no stream left to parse, it will await new input.
The reason your loop is infinite is because it failed to parse the token to an integer and isn't increasing the index. There are two ways to skip the invalid input. nextLine() will skip the rest of the stream waiting. For example, if the input was "1 abc 2"
in.nextInt(); // equals 1
// in.nextInt() would fail
in.nextLine(); // equals "abc 2" and if put in your catch would clear the stream
However, if you want to keep trying subsequent tokens (in this case skip "abc" but try "2", which is valid), next() is more appropriate because it will just skip over one token.
try(){
// validate input
int num = in.nextInt();
}
catch(Exception e){
System.out.println("Ignoring your faulty input");
in.next();
}

How do I check to see if the input is an integer?

Very Frustrated at my professor, because she did not teach try and catch concepts, neither did she teach us about throw exceptions either, so it is very difficult for me to do this program. The objective is to make a program where the user is asked to input an integer that prints "Hello World" that many times of the integer. The problem is I cannot check to make sure the user input is an integer. For instance, if the user chose to type a character or a double, how do I implement that into my code? And I cannot use throw exceptions or try and catch because we did not learn them yet.Thanks guys!!!
import java.util.Scanner;
public class PrintHelloWorld
{
public static void main( String[] args )
{
Scanner scan = new Scanner(System.in);
int number;
System.out.println("Please enter an integer that shows the " +
"number of times to print \"Hello World\" : ");
//store count
number = scan.nextInt();
System.out.print("Your integer is " + number);
int remainder = number%1;
int counts = 0;
if( number>0 && remainder == 0)
{
while(counts <= number)
{
System.out.println("Hello World!");
counts++;
}
}
else
System.out.print("Wrong, choose an integer!");
}
}
scan.hasNextInt()
will check to see if the next value in the input stream is an integer.
as such:
int number = -1;
System.out.println("Please enter an integer that shows the " +
"number of times to print \"Hello World\" : ");
//store count
if (scan.hasNextInt()) number = scan.nextInt();
if (number != -1) System.out.print("Your integer is " + number);
You can use a loop and validate the input with a regex, like this:
Scanner scan = new Scanner(System.in);
String input = null;
while (true) {
input = scan.nextLine();
if (input.matches("\\d+")) {
break;
}
System.out.println("Invalid input, please enter an integer!");
}
int number = Integer.parseInt(input);
This will keep asking for input until a valid integer is entered.
And I cannot use throw exceptions or try and catch because we did not
learn them yet.
For a first attempt, you could create a method that accepts a String as parameter. You will loop through all the chars of this String and check if each char is a digit. While this method returns false, re-ask the user for a new input.
Then use Integer.valueOf to get the int value..
public static boolean isNumber(String input)
You will have to use sc.nextLine() to get the input
The method Character.isDigit and toCharArray() will be useful

Categories

Resources