I'm making a program with Java that needs to involve some error checking. I can stop users from entering bad numerical inputs like this (assume the input scanner has already been created):
while (n == 0){
System.out.println("Can't use 0 as a denominator! Please enter a real, nonzero number");
n = input.nextInt();
}
But how do I stop users from entering an invalid string? I can't use !=, because strings can only be compared with the string.equals() method, right? So, is there a while not loop? ie:
while !(string.equals("y") || string.equals("n")){
//here have code
}
Or something of that nature?
While there is no such thing as a while-not loop, you can always invert the condition:
while (!(string.equals("y") || string.equals("n"))){
This is read, "while the string is not equal to "y" or "n"".
You could also apply DeMorgan's identity to rewrite this as:
while (!(string.equals("y")) && !(string.equals("n"))){
which is a bit clearer as "While the string isn't equal to "y" and isn't equal to "n"".
There isn't a while-not instruction, but you can simply negate the condition in a normal while loop. Try this:
while (!string.equals("y") && !string.equals("n"))
Or even better, to guard against the case where the string is null and/or it's in a different case:
while (!"y".equalsIgnoreCase(string) && !"n".equalsIgnoreCase(string))
You almost get it, just change where you position your !
like this:
while (!(string.equals("y") || string.equals("n")))
Why not try regex?
Scanner sc = new Scanner(System.in);
String string = sc.nextLine();
while (!string.matches("(?i)^(?:y|n|yes|no)$"))
{
System.out.println("Invalid input...");
string = sc.nextLine();
}
boolean answer = string.matches("(?i)^(?:y|yes)$");
Related
So I am trying to validate whether the user typed in a Yes or No and to continue asking until they type in one or the other. This is my code so far.
System.out.println("Would you like a Diamond instead of a Pyramid? Type Yes or No");
String input2 = scan.nextLine();
boolean d = input2.equals("Yes");
System.out.println(d);
while ((d != false) || (d != true)) {
System.out.println("Invalid Input. Please try again");
input2 = scan.nextLine();
d = input2.equals("Yes");
System.out.println(d);
}
Where am I going wrong? I am new to java. Any help would be greatly appreciated.
Edit: I am awful at writing. What I am going for is this type of logic.
Ask the user if they would like a diamond instead of a pyramid.
a. The user must type “Yes” or “No”.
b. If the user types neither of these, ask again until they provide appropriate input.
You are ending up having an infinite loop at
while ((d != false) || (d != true))
since d being a boolean even when updated would either be true or false and in both the cases would satisfy the above condition. Instead you can change it to
System.out.println("Would you like a Diamond instead of a Pyramid? Type Yes or No");
String input2 = scan.nextLine();
boolean d = input2.equalsIgnoreCase("Yes") || input.equalsIgnoreCase("No"); // confirms if the user input is Yes/No or invalid other than that
....
while (!d) { // d==false ' invalid user input
System.out.println("Invalid Input. Please try again");
input2 = scan.nextLine();
d = input2.equalsIgnoreCase("Yes") || input.equalsIgnoreCase("No");
System.out.println(d);
// also printing a boolean would print either true or false base on your input; you migt want to perform some other action
} // this would exit on user input "Yes"
Booleans can ONLY equate to true or false so your while loop is going to execute no matter what because d will be true or it will be false. I think you want to just do
while (d != true)
You are using or(||) operator in your conditions whenever user typed one of your condition is false and other is true so that's why its not working fine.
if you want to stop asking at true value write below condition.
while(d != true)
Fairly new to java and programming.
Wrote this recursive method, with the objective of asking for a valid string that is both an integer and greater than 0:
private int getDimension(String tableElement){
Integer Input= 0;
System.out.println("Define table rows "+tableElement+"'s."
+"Enter an integer >= 1:");
if( !Reader.hasNextInt() || (Input=Input.parseInt(Reader.nextLine())) <= 0)
return getDimension(tableElement);
return Input;
}
I'd like to stick to using a short and recursive method. It seems to handle the >= 0 logic fine, but blows up when i pass it something other than an integer.
Can someone explain why does that happen to me please?
hasNextInt() doesn't actually consume your input, so you're stuck with the same non-int input on your next call.
Simply spoken, your code doesn't make much (any?) sense.
First of all, there is not really a point in using a recursive method that asks the user for input; and that does not at all do anything about the argument passed to it!
private int getDimension(String tableElement){
Integer Input= 0;
Bad: you keep up mixing int and `Integer. They are not the same. And - read about java coding style guides. Variable names start lower case!
if( !Reader.hasNextInt() || (Input=Input.parseInt(Reader.nextLine())) <= 0)
The first condition gives:
true: when there is NO int ...
false: when there is an int
true leads to: calling your method again without retrieving a value from the reader.
false leads to parsing an int; and checking its value for <= 0.
In one case, you are doing a recursive call; completely ignoring the input you got from the reader; in the other case, you returning 0; or that value in input.
Solution: do something like:
while (true) {
if (reader.hasNextInt()) {
input = reader.nextInt();
break;
}
// there is no number!
read.nextLine(); // consume & throw away non-number!
print "Enter a number"
}
instead.
But seriously: start with throwing away this code.
Final side note: you do Input.parseInt() ... but that is a static method on the Integer class. Just call that as Integer.parseInt() instead! But as said; throw away your code; and learn how to properly use that Scanner class; start reading here.
Because the user can enter anything, you must always read in the line, then compare it:
String num = Reader.nextLine();
return num.matches("[1-9][0-9]*") ? Integer.parseInt(num) : getDimension(tableElement);
Here I've use regex to figure out if it's a positive number; the expression means "a 1-9 char followed by 0 or more of 0-9 chars"
I'm trying to learn java but I'm stuck trying to do a single program which concerns Do While Statement with two conditions. Specifically, I want a method to run until the user write "yes" or "no". Well, down there is my thing, what is wrong with it?
String answerString;
Scanner user_input = new Scanner(System.in);
System.out.println("Do you want a cookie? ");
do{
answerString = user_input.next();
if(answerString.equalsIgnoreCase("yes")){
System.out.println("You want a cookie.");
}else if(answerString.equalsIgnoreCase("no")){
System.out.println("You don't want a cookie.");
}else{
System.out.println("Answer by saying 'yes' or 'no'");
}while(user_input == 'yes' || user_input == 'no');
}
}}
I'd do something similar to Tim's answer. But to do things the way you were trying to do them, you have a lot of problems that need to be fixed:
(1) String literals in Java are surrounded by double quote marks, not single quote marks.
(2) user_input is a Scanner. You can't compare a scanner to a string. You can only compare a String to another String. So you should be using answerString in your comparison, not user_input.
(3) Never use == to compare strings. StackOverflow has 953,235 Java questions, and approximately 826,102 of those involve someone trying to use == to compare strings. (OK, that's a slight exaggeration.) Use the equals method: string1.equals(string2).
(4) When you write a do-while loop, the syntax is do, followed by {, followed by the code in the loop, followed by }, followed by while(condition);. It looks like you put the last } in the wrong place. The } just before the while belongs to the else, so that doesn't count; you need another } before while, not after it.
(5) I think you were trying to write a loop that keeps going if the input isn't yes or no. Instead, you did the opposite: you wrote a loop that keeps going as long as the input is yes or no. Your while condition should look something like
while (!(answerString.equals("yes") || answerString.equals("no")));
[Actually, it should be equalsIgnoreCase to be consistent with the rest of the code.] ! means "not" here, and note that I had to put the whole expression in parentheses after the !, otherwise the ! would have applied only to the first part of the expression. If you're trying to write a loop that does "Loop until blah-blah-blah", you have to write it as "Loop while ! (blah-blah-blah)".
I might opt for a do loop which will continue to take in command line user input until he enters a "yes" or "no" answer, at which point the loop breaks.
do {
answerString = user_input.next();
if ("yes".equalsIgnoreCase(answerString)) {
System.out.println("You want a cookie.");
break;
} else if ("no".equalsIgnoreCase(answerString)) {
System.out.println("You don't want a cookie.");
break;
} else {
System.out.println("Answer by saying 'yes' or 'no'");
}
} while(true);
In my if statement, I'm trying to check if the first letter of a string is either Y or y, and then proceed as such. Below is what I have, but I don't believe it to be correct.
System.out.print("Do you wish to do another calculation (Yes/No): ")
option = scan.next();
if (option.substring(0,1) == "N" && option.substring(0,1) == "n" )
{
System.out.println("Have a good day");
System.exit(0);
}
bmi.setOption(option);
I instantiated option as String option = " "; earlier on in my program. I know how to check if strings equal a certain character, however am having trouble checking to see if only the FIRST character of the string is equal to something.
Thank you!
if (Character.toLowerCase(option.charAt(0)) == 'n')
The first char can't be both "N" and "n", looks like you want it to be "N" or "n"
if (option.substring(0,1).equals("N") || option.substring(0,1).equals("n") )
We had == before which is more like a memory comparison we want to compare value so we use equals
I'm having trouble with passing a string and double to another class because it keeps on crashing at double cost = input.nextDouble();. Also, i was wondering if i am correct with the appending method used in public boolean addPARTDETAILS(String partDESCRIPTION, double partCOST).
For example. If the user enters the parts and cost, i want it to store that in a list and print it out with the cost appended.
Parts used:
brake pads ($50.00)
brake fluids ($25.00)
Note. Assuming that i have declared all variables and the array.
System.out.print("Enter registration number of vehicle");
String inputREGO = input.next();
boolean flag = false;
for(int i=0; i<6; i++){
if(inputREGO.equalsIgnoreCase(services[i].getregoNUMBER())){
System.out.print("Enter Part Description: ");
String parts = input.nextLine();
double cost = input.nextDouble();
services[i].addPARTDETAILS(parts, cost);
//System.out.println(services[i].getregoNUMBER());
flag = true;
}
}if(flag==false);
System.out.println("No registration number were found in the system.");
public boolean addPARTDETAILS(String partDESCRIPTION, double partCOST){
if(partDESCRIPTION == "" || partCOST <= 0){
System.out.println("Invalid input, please try again!");
return false;
}
else{
partCOST=0;
StringBuffer sb = new StringBuffer(40);
String[] parts = new String[50];
for (int i=0;i<parts.length;i++){
partDESCRIPTION = sb.append(partCOST).toString();
}
System.out.println(partDESCRIPTION);
totalPART+=partCOST;
return true;
}
}
it keeps on crashing at double cost = input.nextDouble();.
It is highly unlikely that your JVM is crashing. It is far more likely that you are getting an Exception which you are not reading carefully enough and have forgotten to include in your question.
It is far more likely your code is incorrect as you may have mis-understood how scanner works. And so when you attempt to read a double, there is not a double in the input. I suspect you want to call nextLine() after readDouble() to consume the rest of the the line.
I suggest you step through the code in your debugger to get a better understanding of what it is really doing.
Just to expand a bit on Joop Eggen's and Peter Lawrey's answers because I feel some may not understand.
nextLine doesn't play well with others:
nextDouble is likely throwing a NumberFormatException because:
next, nextInt, nextDouble, etc. won't read the following end-of-line character, so nextLine will read the rest of the line and nextDouble will read the wrong thing.
Example: (| indicates current position)
Start:
|abc
123
def
456
After nextLine:
abc
|123
def
456
After nextDouble:
abc
123|
def
456
After nextLine (which reads the rest of the line, which contains nothing):
abc
123
|def
456
Now nextDouble tries to read "def", which won't work.
If-statement issues:
if(flag==false);
or, rewritten:
if(flag==false)
;
is an if statement with an empty body. Thus the statement following will always execute. And no need to do == false, !flag means the same. What you want:
if (!flag)
System.out.println("No registration number were found in the system.");
String comparison with ==:
partDESCRIPTION == ""
should be:
partDESCRIPTION.equals("")
or better:
partDESCRIPTION.isEmpty()
because == check whether the strings actually point to the exact same object (which won't happen unless you assign the one to the other with = at some point, either directly or indirectly), not just whether the have the same text (which is what equals is for).
Data dependent error.
if(flag==false);
System.out.println("No registration number were found in the system.");
should be (because of the ;):
if (!flag) {
System.out.println("No registration number was found in the system.");
}
And
partDESCRIPTION == ""
should be:
partDESCRIPTION.isEmpty()