Keep on prompting user after invalid input - java

Now I know that there is a thread called "Validating input using java.util.Scanner". I already looked there and that thread only answered 1/2 of my problems. The other half is when someone enters a number greater than 2 I get Array Index Out of Bounds Exception. I just need help on if someone enters a 3 for either row or column, the console should prompt something like this:
"Enter the coordinates to place an 'X'. Row then Column."
//enters 3 and 3
"Please enter a valid input"
It would keep and asking the user for a valid number until he gives one.
Would I need to do something like the !keyboard.hasNextInt() but for integers? And that would run smoothly with the rest of my code?

You could use a do-while loop. Something like
do {
//prompt
//input
} while (input not valid);
Where prompt and input should be replaced by code to prompt the user and accept input. In the while section, check if input is valid.

You're question isn't too clear but I'll try to make sense of it.
I'm assuming you've named your scanner "keyboard"
Before I try running this code, the first problem I can see is this (Note that I grabbed this from your code before you edited the question):
while (board[row][col] != ' ')
{
System.out.println("Already occupied space");
System.out.println("Choose again");
row = keyboard.nextInt();
col = keyboard.nextInt();
}
Earlier, you made sure that the user enters integers. However, you have abandoned that completely in this case.
Assuming you're trying to avoid an error if the user enters something other than an integer, this is what I would do:
while(true){
boolean valid = true;
if(!keyboard.hasNextInt()){
valid = false;
keyboard.next();
}
else{
row = keyboard.nextInt();
}
if(!keyboard.hasNextInt()){
valid = false;
keyboard.next();
}
else{
col = keyboard.nextInt();
}
if (valid && (row > 2 || col > 2)){
System.out.println("Please enter a valid input");
continue;
}
else if(!valid){
System.out.println("Please enter a valid input");
continue;
}
else
break;
}
There are a couple reasons this code might seem a bit long. First off, we're trying to test if the input is an integer before we attempt to store it as an int. Secondly, we want to compare the input after we store it successfully to see if it's less than 3. If the input isn't an integer, the boolean "valid" will be false. The way a compiler works, if valid is false in the if statement it will ignore anything to the right of the &&, avoiding an error.
I admit, this is using some commands that I haven't learned before, so this might not be the most efficient way. But you get the idea :)
P.S. You should probably throw the above code into a method.

Related

How to strictly allow exactly ONE char as input using SCANNER reader with reference to my code?

The code below is for a simple calculator with the four basic mathematical operators. It is a working program, it works as expected. However, I have a few questions to understand and improve both my program as well as my understanding of Java. (I have used google but the amount of redundant info confuses me and haven't found any perfect answers on StackOverflow too, though there are dozens of related questions. Believe me, I did tried before posting here).
How can I make sure that the user input is exactly and strictly one char?
here in my program, it accepts more than one character (+-*) but operates on the first char (+) only. I want to make sure more than one character is not accepted as input.
After successful execution of the program, how can I somehow let the user repeat the main method? I mean, a user adds two numbers, gets his answer and he wants to do another calculation, maybe multiply two numbers this time. I can ask the user for yes or no to continue but how do I take him/her back to the beginning? (will a loop work? how?)
A the end of the program I used two methods to output a message. The system.out.print works fine but the JOptionPane method doesn't display the message and the program doesn't terminate (I have commented it out). I would like to understand why?
Is the default case required in the switch? And Am I following the correct code structure? (the arrangements and uses of curly braces)
NB: As I said this calculator works fine and can be used by newbies like myself to better understand the concept as I have commented on every detail. Please understand that I couldn't add everything in the question title due to limits...
package mycalculator;
import javax.swing.JOptionPane;
import java.util.*;
public class MyCalculator{
public static void main (String [] args){
// Let us code a simple calculator//
// Variable type declarations//
char OP;
int firstNum;
int secNum;
// Display an explanation of what this program does//
System.out.println("This is a simple calculator that will do basic
calculations such as :"
+ "\nAddition, Multiplication, Substraction and Division.");
// Create a scanner object to Read user Input.//
Scanner input = new Scanner(System.in);
// Ask user to input any positive number and read it//
System.out.println("Enter Any positive number followed by pressing
ENTER.");
firstNum = input.nextInt();
// Ask user to input/decide his choice operator and read it //
System.out.println("Enter a valid OPERATOR sign followed by pressing
ENTER.");
OP = input.next().charAt(0);
// Loop the below statement till one of the four (+,-,*,/) is entered.//
while(OP != '+' && OP != '-' && OP != '*' && OP != '/'){
System.out.println("Please Re-enter a valid Operator (+,-*,/)");
OP = input.next().charAt(0);}
// Ask user for any second number and read it//
System.out.println("Enter your Second number followed by an ENTER
stroke.");
secNum = input.nextInt();
// Various possible Resolution based on OP value.//
int RSum = firstNum+secNum;
int RSubs= firstNum-secNum;
int RPro = firstNum*secNum;
double DPro = firstNum/secNum;
// Conditional statements for Processing Results based on OP and display.//
switch(OP){
case '+': System.out.println("The Resulting sum is "+ RSum);
break;
case '-': System.out.println("The Resulting sum is "+ RSubs);
break;
case '*': System.out.println("The Resulting Product is "+ RPro);
break;
case '/': System.out.println("The Resulting Divisional product is "+
DPro);
break;
//Maybe the default case is actually not needed but is added for totality//
default : System.out.println("Try Again");
break;
}
// The following code maybe deleted, it is for experimental purpose//
// Just checking if additional statements executes after a program
completes//
System.out.println("Test Message ");
// JOptionPane.showMessageDialog(null, "The Process Ends Here!");
//The test message works fine//
//The JOptionPane statement don't work and program doesn't end. WHY?//
}
}
How can I make sure that the user input is exactly and strictly one
char? here in my program, it accepts more than one character (+-*) but
operates on the first char (+) only. I want to make sure more than one
character is not accepted as input.
If you use console application and Scanner, only thing that you can do is read a String and check its length. In case you use Swing, you could implement KeyPressListener and proceed exactly after user press a button (but not for console application).
After successful execution of the program, how can I somehow let the
user repeat the main method? I mean, a user adds two numbers, gets his
answer and he wants to do another calculation, maybe multiply two
numbers this time. I can ask the user for yes or no to continue but
how do I take him/her back to the beginning? (will a loop work? how?)
You can't repeat main method. In Java main method is been executing only once. To repeate your code, you could wrap whole main method content to the infinite loop or move the content to the separate method and call it from the loop in the main method.
A the end of the program I used two methods to output a message. The
system.out.print works fine but the JOptionPane method doesn't display
the message and the program doesn't terminate (I have commented it
out). I would like to understand why?
JOptionPane works only for graphic application (Swing/AWT). This is not available in console. You have only standard input and output there.
Is the default case required in the switch? And Am I following the
correct code structure? (the arrangements and uses of curly braces)
No, default case is optional by JVM syntax. I remember, that e.g. in C++ there was reccomendation to place it (event empty), to exclude side effects of compilators. I do not know, is there such reccomendation in Java, but when I use switch, I prefer to always add it to exclude logical problem (but this is definetly optional according to syntax case). You use switch correctly.
public static void main(String[] args) {
System.out.println("This is a simple calculator that will do basic calculations such as :"
+ "\nAddition (+)"
+ "\nMultiplication (*)"
+ "\nSubtraction (-)"
+ "\nDivision (/)");
System.out.println();
try (Scanner scan = new Scanner(System.in)) {
while (true) {
System.out.println("Enter Any positive number followed by pressing ENTER.");
int first = scan.nextInt();
System.out.println("Enter a valid OPERATOR (+,*,-,/) sign followed by pressing ENTER.");
String operator = scan.next();
while (operator.length() != 1 || !"+*-/".contains(operator)) {
System.out.println("Please Re-enter a valid Operator (+,-*,/)");
operator = scan.next();
}
scan.nextLine();
System.out.println("Enter your Second number followed by an ENTER stroke.");
int second = scan.nextInt();
if ("+".equals(operator))
System.out.println("The Resulting sum is " + (first + second));
else if ("*".equals(operator))
System.out.println("The Resulting mul is " + (first * second));
else if ("-".equals(operator))
System.out.println("The Resulting sub is " + (first - second));
else if ("/".equals(operator))
System.out.println("The Resulting div is " + ((double)first / second));
System.out.println();
System.out.println("Do you want to exit ('y' to exit)?");
if ("y".equals(scan.next()))
return;
System.out.println();
}
}
}
1) you can check size of string input.next() .If it is one then continue else again prompt for operator choice .
2)I would suggest better create a different method and put all logic in it and call it the number of time you want or call infinite number of times.
4)Should switch statements always contain a default clause?

JAVA: verify user input for one character

this is my first time asking a question. If I'm breaking any rules let me know please :)
I want to verify that the user only types in only one character and store in a variable I have already declared initially. As well, loop back the question for user to type in again if they did not do what they are asked for
Here is a what I have done so far
import java.util.Scanner;
public class arraytesting {
public static void main(String[] args) {
Scanner myKeyboard = new Scanner(System.in);
int user_Choice;
int rowAndcolumns;
char[][] user_Array;
char user_Char;
do {
System.out.print("Enter your choice (1 to 9): ");
user_Choice = myKeyboard.nextInt();
if (user_Choice < 1 || user_Choice > 9)
System.out.println("Illegal choice, please try again.");
} while (user_Choice < 1 || user_Choice > 9);
switch (user_Choice) {
case 1:
do {
System.out.print("\nHow many rows and columns (min 4 & max 20)? ");
rowAndcolumns = myKeyboard.nextInt();
if (rowAndcolumns < 1 || rowAndcolumns > 9)
System.out.println("Illegal choice, please try again.");
} while (rowAndcolumns < 4 || rowAndcolumns > 20);
do {
System.out.print("Which character do you want to fill your square with? (only one character)");
user_Char = myKeyboard.next().charAt(0);
if () // error message for user if they did not type correctly, Idk what to put in the
System.out.println("Illegal choice, please try again.");// boolean for it to compare
System.out.print(user_Char);
} while (); // using do-while loop to loop back question, if they don't type in correctly, i
// would only like for user to type in only one character
break;
}
}
}
I know I can put both of them in one do-while loop, but I want to focus on getting the boolean to check for user input.
edit: I would only like the user to enter only one single character
ex. '#' or 'a'
whereas "##" or "i am typing something that is not one character" is wrong
inside the spaces of if and while are how I want it to be verified
There is no need to do any check for "only 1 character entered". That makes no sense. You can't predict the future, so you cannot know if a user will enter more characters after 1 character has been entered. You will either just take the first character entered and work with it and ignore any potential additional characters - or you have to wait for more than 1 character, essentially breaking the program for users who do the right thing (enter only one character), just to be able to give them an error message when they finally do the wrong thing (enter another character).
That being said, this code:
user_Char = myKeyboard.next().charAt(0);
will actually wait for several characters to be entered until some kind of delimiter (per default some whitespace character, e.g. newline) is entered. That's exactly what you do not want.
You want to get one character from input, and one only. You don't have to care about more characters being entered after that:
user_Char = myKeyboard.next(".").charAt(0);
This tells myKeyboard to return the next String that matches the regex ".", which is any character, and only 1 character.
If you want to validate the entered character, e.g. only alphanumeric characters allowed, you can update your if and while to something like this:
if (!Pattern.matches("[a-zA-Z0-9]", new String(user_Char)))
or even better, use the String returned by myKeyboard.next("."):
String user_String = myKeyboard.next(".");
user_Char = user_String.charAt(0);
if (!Pattern.matches("[a-zA-Z0-9]", user_String))
or you could directly tell myKeyboard to only allow valid characters and skip the entire do/if/while error handling:
user_Char = myKeyboard.next("[a-zA-Z0-9]").charAt(0);
Edit
One thing your code doesn't handle right now is invalid inputs, e.g. letters when you call nextInt. This will actually throw a java.util.InputMismatchException, and you might want to wrap your nextInt() and next(...) calls in try-catch blocks to handle these exceptions.
Please check the code below, based on the discussion with Max, I used the .length() method to check the lenght of the string that the user typed.
You can check the type of the character to avoid the runtime exception in the first if statement using some methods in Character class that you use to check if the input is digit/letter or not ?
Character.isDigit(char)
Character.isLetter(char)
Character.isLetterOrDigit(char)
I also changed some variable names, Java is following the camel case style and class name has to be capitalized. I also refactored some code to check the range of the numbers to git rid of repeating same code on and on, check the method betweenExclusive
package stackoverflow.q2;
import java.util.Scanner;
public class Question2 {
public static void main(String[] args) {
Scanner myKeyboard = new Scanner(System.in);
int userChoice;
int rowAndcolumns;
char[][] user_Array;
char userChar;
do {
System.out.print("Enter your choice (1 to 9): ");
userChoice = myKeyboard.nextInt();
if ( !betweenExclusive(userChoice, 1,9) )
System.out.println("Illegal choice, please try again.");
} while (!betweenExclusive(userChoice, 1,9));
switch (userChoice) {
case 1:
do {
System.out.print("\nHow many rows and columns (min 4 & max 20)? ");
rowAndcolumns = myKeyboard.nextInt();
if (!betweenExclusive(rowAndcolumns ,1 , 9))
System.out.println("Illegal choice, please try again.");
} while (!betweenExclusive(rowAndcolumns ,4 , 20));
String input;
while (true){
System.out.print("Which character do you want to fill your square with? (only one character)");
input = myKeyboard.next();
// error message for user if they did not type correctly, Idk what to put in the
// boolean for it to compare
if ( input.length()>1){
System.out.print("Illegal character, try again please !!! ");
}else{
userChar = input.charAt(0);
System.out.print(userChar);
break;
}
} // using do-while loop to loop back question, if they don't type in correctly, i
// would only like for user to type in only one character
break;
}
}
public static boolean betweenExclusive(int x, int min, int max)
{
return x>=min && x<=max;
}
}

I need to get my Java program to start back at the beginning after an invalid input

I'm currently working on an assignment for school and I am almost done but I just have one large problem I need to fix before I can add the final bit.
I need to create a program that prompts you to enter either 1 or 2, Afterwards it asks you to enter three words/names and saves them into an array.
Then, depending on whether you picked 1 or 2, it prints them in alphabetical order or flips around the lowercase and uppercase letters. I didn't add that part yet because I'm trying to fix a problem related to the very first input.
When you input a number other than 1 or 2, I am instructed to display an error message and ask for input again. I am pretty sure what I need to do is get the entire program to go back to the beginning because copy/pasting the entire program again would be bad, lol
A big problem is probably that I'm using if/else statements with for loops inside when I might need to put the entire thing inside a loop? But I'm not sure what condition I would use to start the loop if I put the entire code in it. I must be missing something here.
With what I have now, it gets stuck saying invalid input even if you put in a 1 or 2.
import java.util.Scanner;
public class IsabellaPiantoniLab5 {
public static void main (String[]args) {
//Ask for input
Scanner input = new Scanner(System.in);
System.out.print("Please choose either a number 1 or number 2.");
int numChoice = input.nextInt();
//if choice is 1 or 2
if (numChoice == 1 || numChoice == 2) {
System.out.println("Please enter three names: ");
String nameInput[] = new String[4];
//input loop
for (int i= 0; i < nameInput.length; i++) {
nameInput[i] = input.nextLine();
}
System.out.println("Values are:");
//display values if 1
if (numChoice == 1) {
for (int i=1; i<4; i++) {
System.out.println(nameInput[i]);
}
}
//display values if 2
else if (numChoice == 2) {
for (int i=1; i<4; i++) {
System.out.println(nameInput[i]);
}
}
}
//retry if invalid------i restart from the beginning if this happens
else if (numChoice != 1 || numChoice != 2) {
System.out.println("Invalid value. Please try again.");
//continue;
}
}
}
System.exit(0);
This will terminate the app, thus you can start it again using command line ( START [your app path])
Or
RunTime.getRuntime().exec(“Your app”);
System.exit(0);
Edit I misunderstood the question, I thought you wanted to restart the whole app
After discussing the approach with #csm_dev
It is way either to ask for the user input one more time by emptying the field and showing a message “please enter a valid input” with a clarification message

Continuously ask for a user input

I have two available options for a user to input, and what I am trying to accomplish is if the user does not enter either of the inputs the program will continuously ask them again until they enter a valid one. Here is the code right now
String userLIB = user_input.next();
if (userLIB.contentEquals(UBC.acro)){
printDetails(UBC);
} else {
if (userLIB.contentEquals(ORL.acro)){
printDetails(ORL);
} else {
while (!userLIB.contentEquals(UBC.acro) || !userLIB.contentEquals(ORL.acro)){
System.out.println("Invalid input");
break;
}
}
}
I have a break to keep the code from looping the "Invalid input" indefinetly but it just ends the program right now which isn't what I want to happen. Is there a way to make the program go back to the start of the if statement?
You're breaking your code when the Invalid input condition is met.
Do as following,
String userLIB = "";
do {
userLIB = user_input.next();
if (userLIB.contentEquals(UBC.acro)){
printDetails(UBC);
} else if (userLIB.contentEquals(ORL.acro)) {
printDetails(ORL);
} else {
System.out.println("Invalid input. Try again!");
}
} while (!userLIB.contentEquals(UBC.acro) || !userLIB.contentEquals(ORL.acro));
This, tries to get the only 2 possible inputs and terminate the loop.
Else will loop again and again, until the required input is provided.
I figured it out with the help of #Carcigenicate, I put a while loop outside of the whole code and then put a userLIB = user_input.next(); inside of the incorrect if statement. Also thanks to #Sridhar for giving an answer that also works

Preventing the user from entering identical elements(within a malfunctioning try catch)

So the following code is like a simple game,where the objective to to guess the correct numbers(which are 1 to 5).Anything else is incorrect and the user is given a warning message if they enter similar numbers.The comments would explain the loops and variables declared.
The only problem I have with this code is that I inserted a try catch to take care of strings and that doesn't seem to work.If a string is entered,the while loop continues infinitely.
Also,I realize there are a loop pf looping and conditional statements present in my code,but I couldn't think of anything else.If you have any recommendations to reduce the number of loops and if statements,your help would be greatly appreciated.
public class Tries {
public static void main(String[]args)
{
boolean dataType=false;
int Inp;
Scanner a=new Scanner(System.in);
//The arraylist,List, contains the input that the user enters.Only correct input is entered(1 to 5).
ArrayList<Integer> List=new ArrayList<Integer>();
//This determines how many times the for loop is going to execute.Say the user enters 4,and enters 4 correct inputs,the program will exit.The variable num basically determines what the size of the arraylist List is going to be.
System.out.println("How many tries?");
int num=a.nextInt();
boolean datatype=false;
for(int j=0;j<num;j++)
{
//This while loop is for the try catch.
while(!datatype)
{
Scanner sc=new Scanner(System.in);
//This while loop ensures that the user re enters input when anything other than the correct numbers are entered.
while(List.size()!=num)
{
try
{
System.out.println("\nPick a number: ");
Inp=sc.nextInt();
if(Inp==1 || Inp==2 || Inp==3 || Inp==4 || Inp==5)
{
datatype=true;
System.out.println(j);
if(List.size()==0)
{
List.add(Inp);
}
else if(List.size()>0)
{
if(List.contains(Inp))
{
System.out.println("Already entered.Try again.");
}
else if(!List.contains(Inp))
{
List.add(Inp);
System.out.println("Added");
dataType=true;
System.out.println(List);
}
}
}
else
{
System.out.println("Option not available.");
datatype=false;
}
}
catch(Exception JavaInputMismatch)
{
System.out.println("Option not available.Try again.");
datatype=false;
}
}
}
}
}
}
So, when Inp=sc.nextInt(); fails because the user enters an invalid number, then an InputMismatchException gets thrown. Then you loop again, and eventually attempt to run Inp=sc.nextInt(); again.
The problem though is that the invalid number that was entered is still in the input stream waiting to be read. So in the next loop, when Inp=sc.nextInt(); is attempted again, it doesn't try to read in a new value, it just reads the previous invalid value without allowing you to type anything new. And this keeps happening over and over indefinitely.
The quick fix? You need to clear out the input stream to get rid of the invalid number before attempting to read a new one.
The simplest way to plug that fix in your program is by adding an sc.next(); call in your catch block like this:
catch(Exception JavaInputMismatch)
{
sc.next(); // clear the bad token. Without this, it loops infinitely.
System.out.println("Option not available.Try again.");
datatype=false;
}
There are certainly quite a few other changes/improvements I would make to the program, but I'll admit that I lack the motivation at the moment to address those. Hopefully this will at least unblock you.
EDIT:
I guess I can add a few high level suggestions that can help you:
As was already commented, you shouldn't have 2 Scanner instances reading from System.in.
I would recommend dropping the whole try-catch to detect an invalid number, and instead use sc.hasNextInt() to check before reading the number with sc.nextInt(). Even if you did keep the catch block, I would recommend you make the exception type as specific as possible (e.g. catch(InputMismatchException e)) instead of the catch-all Exception. Otherwise, you risk catching irrelevant exceptions and handling them the wrong way.
You should be able to drop the datatype boolean variable and its associated loop. It's enough that you are looping as long as your list is not full.
In fact, if I'm understanding this correctly, you can probably simplify your loops by only keeping the one that does while(List.size()!=num). I think you can safely get rid of the loop that does for(int j=0;j<num;j++).
Minor detail, but you can express if(Inp==1 || Inp==2 || Inp==3 || Inp==4 || Inp==5) more succinctly like this instead: if(Inp >= 1 && Inp <= 5).
And finally, the logic that determines whether to add the number to the list or not doesn't need to do a bunch of conditions based on the size of the list.
Something like this is sufficient:
if (List.contains(Inp)) {
System.out.println("Already entered.Try again.");
} else {
List.add(Inp);
System.out.println("Added");
System.out.println(List);
}
I hope this helps.

Categories

Resources