I'm trying to make an if statement to catch if the user of the program enters a value besides y or n for the question asked at the end of the program "Continue? (y/n): ". But no matter what the value I input "y", "n", or something invalid I get the message "Invalid input try again" from the console. This is only supposed to happen when the choice is not y or n anyone know why it keeps happening regardless of what I input?
import java.util.Scanner;
public class ProductApp
{
public static void main(String[] args)
{
//display a welcome message
System.out.println("Welcome to the Product Selector ");
System.out.println();
// perform 1 or more selections
Scanner sc = new Scanner(System.in);
String choice = "y";
while (choice.equalsIgnoreCase("y"))
{
System.out.println("Enter Product Code: ");
String productCode = sc.next(); //read the product code
sc.nextLine() ; //discard any other data entered on the line
//make sure the case the user enters for a product code doesn't matter
productCode = productCode.toLowerCase();
// get the Product object
Product p = ProductDB.getProduct(productCode) ;
// display the output
System.out.println();
if (p != null)
System.out.println(p);
else
System.out.println("No product matches this product code. \n");
System.out.println("Product count: " + Product.getCount() + "\n" );
// see if the user wants to continue
System.out.println("Continue? (y/n): ");
choice = sc.nextLine() ;
System.out.println();
if( !choice.equalsIgnoreCase("y") && !choice.equalsIgnoreCase("n") );
{
System.out.println("Invalid input try again");
continue;
}
}
}
}
also wherever I get the message "Invalid input try again" the program asks for a new input once but then moves on whether it's valid or not. it runs again if its "y" and closing if its anything else instead of asking a second time for a valid input.
Your condition is not working because you have ; after your if statement.
if( !choice.equalsIgnoreCase("y") && !choice.equalsIgnoreCase("n") );
^^
Change
if( !choice.equalsIgnoreCase("y") && !choice.equalsIgnoreCase("n") );
{
System.out.println("Invalid input try again");
continue;
}
TO
if(!(choice.equalsIgnoreCase("y") || choice.equalsIgnoreCase("n")))
{
System.out.println("Invalid input try again");
continue;
}
your condition is not correct it should be
if(!choice.equalsIgnoreCase("y") && !choice.equalsIgnoreCase("n")){
// choice is not y or n
}
choice.equalsIgnoreCase("y") && choice.equalsIgnoreCase("n") it will never be true
because choice may be either y or n but not both
Make it a while statement if you want it to ask until you input y or n. Otherwise it will jump to the big while loop and exit since the big one is asking for
while (choice.equalsIgnoreCase("y"))
so, the inner loop would look like this:
while( !choice.equalsIgnoreCase("y") && !choice.equalsIgnoreCase("n") )
{
System.out.println("Invalid input try again");
//continue; //not needed
}
EDIT: Another approach would be to treat only 'y' as yes and everything else as 'n'
// pseudocode
while (!choice.equalsIgnoreCase("n")) {
// do your thing
if (!(choice.equalsIgnoreCase("y") || choice.equalsIgnoreCase("n"))) {
choice = "n"; // so exit
}
}
check your condition. it should be:
if(!(choice.equalsIgnoreCase("y") || choice.equalsIgnoreCase("n") ))
{
System.out.println("Invalid input try again");
continue;
}
if( !(choice.equalsIgnoreCase("y") || choice.equalsIgnoreCase("n")) )
{
System.out.println("Invalid input try again");
continue;
}
Try this .
I think you should change if(!choice.equalsIgnoreCase("y") && !choice.equalsIgnoreCase("n")); to if(!choice.equalsIgnoreCase("y") || !choice.equalsIgnoreCase("n")){. Cause using && checks for both condition to be true and this can never happen since choice can contain only one value.
Related
I recently started learning Java as I have a keen interest in programming. I am currently creating an application that calculates a person's BMI.
Question: Is there a way to return to the previous statement when the user has made a mistake on instead of restarting the whole program (EG: when the line Please enter your weight in pounds executed, the user input a non-integer value and an error prompts out saying Invalid Input, it will then return to the previous line that the user made an error -> Please enter your weight in pounds executed).
If yes, how so?
import java.util.Scanner;
import java.text.DecimalFormat;
public class Body_Mass_Calculation {
private static int gender, inputAnswer;
private static boolean wenttocatch;
private static double myBMI, heightInch, weightPound, weightKilo, heightMeter;
private static Scanner input_1 = new Scanner(System.in);
private static DecimalFormat df2 = new DecimalFormat("#.##");
//Questions + Calculation
static void myMethod() {
try {
System.out.println("Please enter gender. 1-- Male 2--Female");
gender = input_1.nextInt();
while (gender > 2 || gender < 1) {
System.out.println("Invalid input!");
System.out.println("Please enter gender. 1-- Male 2--Female");
gender = input_1.nextInt();
}
if (gender == 1 || gender == 2) {
System.out.println("Please enter your height in inches. ");
heightInch = input_1.nextInt();
System.out.println("Please enter your weight in pounds. ");
weightPound = input_1.nextInt();
heightMeter = heightInch * 0.0254;
weightKilo = weightPound * 0.45359237;
myBMI = weightKilo / (heightMeter * heightMeter);
}
if (gender == 1) {
if (myBMI >= 27.8)
System.out.println("Your body-mass-index is " + df2.format(myBMI) + " this is considered high ! \n \n");
else
System.out.println("Your body-mass-index is " + df2.format(myBMI) + " this is not considered high ! \n \n");
}
if (gender == 2) {
if (myBMI >= 27.3)
System.out.println("Your body-mass-index is " + df2.format(myBMI) + " this is considered high ! \n \n");
else
System.out.println("Your body-mass-index is " + df2.format(myBMI) + " this is not considered high! \n \n");
}
System.out.println("Do you wish to continue? Enter: 1 -> Yes, 2 -> No.");
inputAnswer = input_1.nextInt();
System.out.println("Invalid Input !");
if (inputAnswer == 2) { //If input = 2, Program executes line below
System.out.println("Thank You for using this shitty app !");
System.exit(2);
} else if (inputAnswer == 1) {
myMethod();
}
} catch
(Exception e) {
input_1.next();
wenttocatch = true;
System.out.println("Invalid input !");
input_1.nextLine();
myMethod();
}
}
public static void main(String[] args) {
//Executes Function/Method
System.out.println("Welcome ! \n ");
myMethod();
}
}
No, you can't. The solution is to write a method that takes care of it. Instead of writing a ton of code and repeating yourself, you use a method to encapsulate some functionality, so that you can invoke it a lot without copying code. For example, instead of:
System.out.println("Please enter gender. 1-- Male 2--Female");
gender = input_1.nextInt();
while (gender > 2 || gender < 1) {
System.out.println("Invalid input!");
gender = input_1.nextInt();
}
you really just want to write something like:
gender = askInt("Please enter gender. 1-- Male 2-- Female", 1, 2);
where the askInt is a method you write which takes the text you want to show as prompt, along with the smallest and largest valid value.
Now that you have this function, you can expand its functionalities and all the code that uses this function gets the functionality automatically. So, if you add 'catch invalid input exceptions and re-ask' functionality to this one method, ALL the questions get it.
int askInt(String prompt, int min, int max) {
int result;
while (true) {
System.out.println(prompt);
result = input.nextInt();
if (result >= min && result <= max) return result;
System.out.println("Invalid input!");
}
}
This basic loop will keep looping until the if clause is triggered, causing the method to return, which is the only way out. You can now add handling for NumberFormatException within this one method, within the while loop. You can't go back to the line that caused the problem, but you can go forward, and in a while loop, going forward automatically jumps back to the start (i.e., that's how to go 'backwards'). So, we mix a while loop (which can go backwards) and a catch block, and that's how to solve the problem. And then we put all this in a method, so that we can write this code only once, instead of having to repeat it every time.
You can do it by using a do { _code1 } while (_condition) which execute the _code until _condition is false.
And _code1 is a try {}catch which will catch any exception (error) thrown from inside the try {} block.Here the exception (error) is thrown if the user enters a character instead of a digit.
System.out.println("Please enter gender. 1-- Male 2--Female");
int gender = 0 ;
do {
try {
if (gender == -1) {
System.out.println("Invalid input!");
System.out.println("Please enter gender. 1-- Male 2--Female");
}
gender = input_1.nextInt () ;
}catch (Exception e){
gender = -1 ;
}
}while (gender > 2 || gender < 1);
I recently started java programming
but I have a problem
i want to write a program. I have a password, I ask the user of the program to enter the password
I want: if the person entered a string, I tell him that please don't enter string
and if the password was right and the type of the password that he entered(int) was right, I tell him OK.
in the test of the program, my problem is that when I entered a wrong password and expect that the program tell me that the pass is wrong, the program just tell me nothing !!
here is my code :
int pass = 123 ;
Scanner password = new Scanner(System.in);
System.out.println("Please Enter Your Password : ");
if (password.hasNextInt() && password.nextInt()==pass)
{
System.out.println("ok");
}
else if (password.hasNextInt())
{
System.out.println("wrong pass");
}
else
{
System.out.println("wrong type");
}
You are using hasNextInt() From Java docs.
Returns true if the next token in this scanner's input can be
interpreted as an int value
So you are asking twice for the input.
Example
Input:
1234 (first Input)
1234 (Then hasNextInt() is asking for input again)
OutPut :
wrong pass
So I made this simple snippet for you can use
Scanner password = new Scanner(System.in);
System.out.println("Please Enter Your Password : ");
int pass = 123;
try {
int myInput = password.nextInt();
if (myInput == pass) {
System.out.println("ok");
}else{
System.out.println("wrong pass");
}
}catch (java.util.InputMismatchException e) {
System.out.println("wrong type");
}
The problem is that Scanner methods like nextInt() consume input that's then no longer available to later Scanner calls.
int pass = 123 ;
Scanner password = new Scanner(System.in);
System.out.println("Please Enter Your Password : ");
if (password.hasNextInt() && password.nextInt()==pass) // line A
{
System.out.println("ok");
}
else if (password.hasNextInt()) // line B
{
System.out.println("wrong pass");
}
else
{
System.out.println("wrong type");
}
So in case of entering a wrong password, e.g. 4321, what happens?
Line A checks password.hasNextInt() as the first half of your condition. The Scanner doesn't know that right now and waits for your console input. You enter 4321, and now the Scanner can check whether that's a valid number (and it does so without consuming the 4321, so that it's still available). It is, so the program continues to the next part of the condition (side remark: were it abc, that first part would be false, and Java would already know that the combined password.hasNextInt() && password.nextInt()==pass condition would be false, without a need to go into the second half, thus not consuming the entry).
Line A now checks the second half password.nextInt()==pass. This calls nextInt(), returning the integer 4321 and consuming the input. Comparing this against your number 123 gives false, so the condition doesn't match. That's what you want so far.
Now in line B you want to check for the case of a number not being 123. But your condition password.hasNextInt() no longer sees the 4321 we entered, as that has been consumed in line A. So it waits for the next input. That's the problem, you're still calling hasNextInt() after consuming the input with nextInt().
You can change your program like this:
int pass = 123 ;
Scanner password = new Scanner(System.in);
System.out.println("Please Enter Your Password : ");
if (password.hasNextInt()) {
if (password.nextInt()==pass) {
System.out.println("ok");
} else {
System.out.println("wrong pass");
}
} else {
pass.next(); // consume the invalid entry
System.out.println("wrong type");
}
[ I reformatted the code snippet in a more Java-typical style, doesn't change the functionality of course, but looks more familiar to me. ]
Of course, Gatusko's exception-based approach works as well, and personally I'd do it his way, but maybe you don't feel comfortable with exceptions right now, so I stayed as close to your approach as possible.
You can use the following piece of code.
public static void main(String[] args){
int pass = 123 ;
Scanner password = new Scanner(System.in);
System.out.println("Please Enter Your Password : ");
if (password.hasNextInt())
{
if(password.nextInt()==pass) {
System.out.println("ok");
}
else {
System.out.println("Wrong password");
}
}
else
{
System.out.println("wrong type");
}
}
What about a while?
int MAX_TRIES = 3
int currentTries = 0;
while (password.hasNextInt() && currentTries < MAX_TRIES) {
if (password.nextInt()==pass) {
// OK!
} else {
// Wrong!
}
currentTries++;
}
if (currentTries == MAX_TRIES) {
// You tried too much
} else {
// Password was a string
}
Try this code, if the input is not an integer then it will throw NumberFormatException, which is caught and displayed.
public static void main(String[] args){
int pass = 123 ;
Scanner password = new Scanner(System.in);
System.out.println("Please Enter Your Password : ");
String enteredPassword ="";
if(password.hasNext() && (enteredPassword = password.next()) !=null){
try{
if(Integer.parseInt(enteredPassword) == pass){
System.out.println("ok");
}else{
System.out.println("wrong pass");
}
}catch (NumberFormatException nfe){
System.out.println("wrong type");
}
}
}
I need to user to enter an int between 1 and 301.
I have this simple loop here to check for user input.
I just want a single number from the user, and if the user enters anything other than an int between 1 and 301, I want to display the print line and prompt the users to try again until they enter a valid input.
while (!sc.hasNextInt()) {
System.out.print("Invalid Input. Please enter a valid number between 1 and 301: ");
sc.next();
}
int numToCheck = sc.nextInt();
// do stuff with numToCheck
This checks that the input is an int, but I can't seem to find a way to give the int input a bound. I tried to assign the user input to a variable and then check the conditions input < 1 or input > 301, but I get InputMismatchException if user enters a letter. How should I store the user input? (I want to store it as an int to check the conditions, but can't do that since I don't know what the user will enter).
Perhaps there is a better design to accomplish all this. Those are welcomed too.
Thanks in advance.
You're not saving the value of the of the input. So your program is waiting on the user to enter a number each time it see "sc.nextInt()" Assign the input to a variable, and then check the condition.
EDIT: okay, I'll go the extra mile for you. See if this works.
***Accounted for the case where the user might enter a character instead of a number.
import java.util.*;
public class HelloWorld{
public static void main(String []args){
Scanner sc = new Scanner(System.in);
int input;
while (true){
if (sc.hasNextInt()){
input = sc.nextInt(); // Assign the next integer to a variable
if (input <= 301 && input >= 1){ // Check if integer meets condition
break; // Condition met, break out of loop
}
}else{
sc.next();
}
System.out.println("Invalid Input. Please enter a valid number between 1 and 301: ");
}
}
}
I ran this code, to see if it would show a better performance than yours.
Scanner sc = new Scanner(System.in);
boolean valid = true;
do {
if (!valid) {
System.out.print("Invalid Input. ");
}
System.out.print("Please enter a valid number between 1 and 301: ");
String input = sc.next();
try {
int value = Integer.parseInt(input);
valid = (value >= 1 && value <= 301);
} catch (NumberFormatException nfex) {
valid = false;
}
} while (!valid);
When the conversion to integer fails, the JVM hangs a little. I believe your problem has more to do with the try / catch mecanism that Scanner performs under the hood, than with design.
Assuming you want only 1 input from the user, try following simple code, which takes input from the user until user enters a valid input.
Scanner in = new Scanner(System.in);
int flag = 0,x=0;
while(flag == 0){
x = in.nextInt();
if(x<1 || x>301){
flag = 0;
System.out.println("Invalid Input.");
}
else{
flag = 1;
}
}
And if you want user to input more than 1 inputs (i.e 3 here), than set a counter that increases with every valid input of the user, as following:
Scanner in = new Scanner(System.in);
int flag = 0,x=0,count = 1;
while(flag == 0){
x = in.nextInt();
if(x<1 || x>301){
flag = 0;
System.out.println("Invalid Input.");
}
else{
//executes when input is valid
if(count == 3){
flag = 1;
}
count++;
}
}
Edit:
If you also want to check whether the input is Integer or not, than you have to add one extra condition in above code. And as you said you want only one input from user rather than 3, you have to change exit condition. Change code as following:
Scanner in = new Scanner(System.in);
int flag = 0,count = 1,x=0,flag1 = 0;
String y;
while(flag == 0){
y = in.next();
flag1 = 0;
try{
x = Integer.parseInt(y);
}
catch(NumberFormatException e){
flag1 = 1;
System.out.println("Invalid Input.");
}
if((x<1 || x>301)&&flag1 == 0){
flag = 0;
System.out.println("Invalid Input.");
}
else if(flag1 == 0){
//executes when input is valid
if(count == 1){ // put count == 3 if you want 3 inputs from user.
flag = 1;
}
count++;
}
}
Here we are taking the input as a String and than converting the String into the Integer by using Integer.parseInt(). If the String is not Integer, than it will throw the exception and we will continue the loop till the valid input is entered by the user.
Use DO WHILE for result
do{
System.out.print("value of x : " + x );
x++;
System.out.print("\n");
}while( x < 20 );
OK ?
I am attempting to create a program thtat does some processing and exits when a given letter is typed.
//1.00usd = .727751euro
int reset = 0;
while(reset == 0)
{
double euro;
double ems;
String input = JOptionPane.showInputDialog(null,"Enter Amount of US Dollar: ");
ems = Double.parseDouble(input);
if (ems < 0)
{
JOptionPane.showMessageDialog(null, "Please enter a real amount of money");
reset = 0;
}
if (ems >= 0)
{
euro = .727751;
ems = ems*euro;
ems = ems*100;
ems = Math.round(ems);
ems = ems/100;
JOptionPane.showMessageDialog(null,"Amount in euros: € " + ems);
}
}
This program is to convert usd to euro and I wanted to know how I can make the program exit when entering the letter "Q".
This is for a an object class so I'm still learning.
Something like
String input = JOptionPane.showInputDialog(null,"Enter Amount of US Dollar: ");
if( input.equals("Q") ) // but the case is important here
{
System.out.println("Bye bye");
System.exit(0);
}
ems = Double.parseDouble(input);
If your question is "how to exit the program", you can call
System.exit(0);
when the user presses a key.
If you just want to "quit" the loop you're in, manage to get the condition true, or use "break" (but you should not need it in your case).
Add this if statement in the while loop.
if(inputString.equalsIgnoreCase("q")) {
System.exit(0);
}
Somehow I am getting some funny play here and I just cant see why.
This method is supposed to make sure that the input is either y or n, and is NOT blank.
I should note this is for school, and the 2 separate error outputs are required.
When I enter a blank line, I get exactly that at the console- a blank line.
After that point, or after a time where I purposely enter bad data, such as x, the very next time I enter a valid data, like y or n, I continue to get the bad data in an endless loop.
What have I done wrong?
public static boolean getContinue(Scanner sc)
{
boolean decision = false;
System.out.println("Continue? Y/N: ");
String userChoice = sc.next();
boolean isValid = false;
while (isValid == false)
{
if (userChoice.equalsIgnoreCase("y"))
{
decision = true;
isValid = true;
}
else if (userChoice.equalsIgnoreCase("n"))
{
decision = false;
isValid = true;
}
else if (userChoice.equals(""))
{
System.out.println("Error! This entry is required. Try again.");
userChoice = sc.next();
}
else if (!userChoice.equalsIgnoreCase("y") | (!userChoice.equalsIgnoreCase("n")))
{
System.out.println("Error! Entry must be 'Y' or 'N'. Try again.");
userChoice = sc.next();
}
}
return decision;
}
NOTE:
Code was amended to include
New console outputs(Still wrong)
FORMATTED RESULTS
Loan amount: $5.00
Yearly interest rate: 500%
Number of years: 5
Monthly Payment: $2.08
Continue? Y/N:
b
Error! Entry must be 'Y' or 'N'. Try again.
y
Error! Entry must be 'Y' or 'N'. Try again.
y
Enter loan amount:
You don't set the variable userChoice to the new value. Change your last if clause to
System.out.println("Error! Entry must be 'Y' or 'N'. Try again.");
userChoice = sc.next();
Because userChoice never changes inside the loop (which is because you don't change it).
Please look at else if part:
else if (!userChoice.equalsIgnoreCase("y") | (!userChoice.equalsIgnoreCase("n")))
here you have done 2 errors:
you have used |, which is bitwise operator, not logical
the logic requires logical AND (&&) to get the cases when the input is not either y or n
SO the correct else-if:
else if (!userChoice.equalsIgnoreCase("y") && (!userChoice.equalsIgnoreCase("n")))
{
System.out.println("Error! Entry must be 'Y' or 'N'. Try again.");
userChoice = sc.next();
}
You have to use sc.nextLine() in order to catch the Empty Blank Line. So replace all the instances of sc.next() with sc.nextLine()