How to make do-loop conditions "when string does not equal" - java

I want to make my do loop run while the input the user made is not equal to the required letters (a-i) For some reason,even when i input the proper letters, it loops forever.
I've tried using switch cases as well as != inside the comparison.
Here is my code:
do {
System.out.println("Please enter the location of your battleship, starting with the first letter value. Make sure it is from the letters a-i.");
lL1=in.nextLine();
if (!lL1.equals("a")||!lL1.equals("b")||!lL1.equals("c")||!lL1.equals("d")||!lL1.equals("e")||!lL1.equals("f")||!lL1.equals("g")||!lL1.equals("h")||!lL1.equals("i")){
System.out.println("Invalid Input. Try again.");
}//End if statement
}while(!lL1.equals("a") || !lL1.equals("b") || !lL1.equals("c") || !lL1.equals("d") || !lL1.equals("e") || !lL1.equals("f") || !lL1.equals("g") || !lL1.equals("h") || !lL1.equals("i"));
My skills in Java are limited but this should work, unless i'm missing something obvious. Any help would be amazing!

Instead of using an operator for each case of the input, you might want to create a list of the accepted answers and then your condition will look like:
while answer is not in accepted answers, ask another input
An example would be:
Scanner scanner = new Scanner(System.in);
List<String> acceptedAnswers = Arrays.asList("a", "b", "c", "d", "e", "f", "g", "h", "i");
String input;
do {
System.out.println(
"Please enter the location of your battleship, starting with the first letter value. Make sure it is from the letters a-i.");
input = scanner.nextLine();
} while (!acceptedAnswers.contains(input));
scanner.close();
System.out.println("Got correct input: " + input);

If you have a negation you need AND to join the conditions not OR.

That's because if you or some not-ed values, they form an and.
Let me explain better.
If you input a, then the first is false (because you not it), and the others are true, so the or condition make the result be true.
You should instead group all the ors and then not it.
e.g.
!(lL1.equals("a") || lL1.equals("b") || lL1.equals("c") || lL1.equals("d") || lL1.equals("e") || lL1.equals("f") || lL1.equals("g") || lL1.equals("h") || lL1.equals("i"))

Please try this:
char lL1;
Scanner scanner = new Scanner(System.in);
do {
System.out.println("Please enter the location of your battleship, starting with the first letter value. Make sure it is from the letters a-i.");
lL1=scanner.next().charAt(0);
}while(lL1!='a' && lL1!='b' && lL1!='c' && lL1!='d' && lL1!='e' && lL1!='f' && lL1!='g' && lL1!='h' && lL1!='i');
Since you are only getting a single character, you can check that it does not match either [a to i] characters as shown above. This is the shortest way to do so by making the check as the condition of the loop. If it fails then the loop will be called.

Related

Java NumberFormatException when using Integer.parseInt

I have truly searched for the answer all over the Internet before coming here and I think that the answer will have something to do with the try/catch statements, but even after watching a couple tutorials on the topic I am not sure on how to implement that.
Anyways, I am trying to do a simple thing in my newbie reminders app that I am making (I am learning Java as my first language for about 3 months now).
I want the program to check the user's input and if it is a certain letter ("R") I want the program to do a certain stuff. If it is an integer from 0 to 100 then I want to do other stuff. And if its neither of them, then I want the "else" statement to work.
The issue that I can't get the "else" statement to work as I get the NumberFormatException error. For example if I enter some other letter i.e. "d" - I get this error message:
Exception in thread "main" java.lang.NumberFormatException: For input
string: "d" at
java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:580) at
java.lang.Integer.parseInt(Integer.java:615) at
mash.Dialogue.startDialogue(Dialogue.java:51) at
mash.Dialogue.newRem(Dialogue.java:27) at
mash.Dialogue.startDialogue(Dialogue.java:38) at
mash.Dialogue.start(Dialogue.java:13) at mash.Main.main(Main.java:9)
Here is the code (I am sorry for any readability issues, this is the first time ever I am showing my code to somebody). You don't have to read the else if statement, as the issue seems to not depend on the text inside of that statement.
I would really appreciate if anybody could point me what is wrong with the code and how I would get to do what I intended. Some newcomer-friendly solution will be much appreciated.
Thank you in advance!
String secondLetter = mash.nextLine();
if(secondLetter.equals("r") || secondLetter.equals("R")) { //if the user enters R - create a new Reminder
newRem();
}
else if((Integer.parseInt(secondLetter) >= 0) && (Integer.parseInt(secondLetter) < maximum)) { //if the user enters number - check task list
tasks.remText(Integer.parseInt(secondLetter));
System.out.println("Enter 'D' to set the reminder as Done. Or enter 'T' to return to the list");
String v = mash.nextLine();
System.out.println(v);
if(v.equals("d")|| v.equals("D")) { //if user enters D - set the reminder as done
tasks.setDone(Integer.parseInt(secondLetter));
System.out.println("The reminder is now added to 'Done' list");
}
else if(v.equals("t")|| v.equals("T")) { //if user enters T - return to the list of reminders
tasks.display();
}
else {
System.out.println("Please enter the correct symbol");
}
}
else {
System.out.println("Enter the correct symbol");
}
You can check your input if it's a valid number before attempting to convert it. For example:
if(!secondLetter.matches("[0-9]+")) {
//it's not a number, so dont attempt to parse it to an int
}
place it in your if/else like this:
if(secondLetter.equals("r") || secondLetter.equals("R")) {
newRem();
} else if(!secondLetter.matches("[0-9]+")){
System.out.println("please type r or R or a number");
} else if((Integer.parseInt(secondLetter) >= 0) && ...
Short answer: docs.oracle.
Complete answer:
You can use Integer.parsInt (String s) only on a string that can be parserized into an integer. The letter "R" can not be a number, so it generates an exception.
if(Character.isLetter(secondLetter) && "R".equalsIgnoreCase(secondLetter)){
do code with "R"
}else if(Integer.parseInt(secondLetter) > 0 && Integer.parseInt(secondLetter) < 100){
do code with 0 < number < 100
}else{
do something else
}

StringIndexOutOFBoundsException: 0

I am a relative beginner to Java and am having an issue with a user controlled do-while loop that accepts user input to repeat. Here is the code at the end of the loop.
System.out.print("Do you wish to continue? (Y for yes " +
"/ N for no)");
input = keyboard.nextLine();
input.length();
repeat = input.charAt(0);
}while (repeat == 'Y' | repeat == 'y');
I know it's throwing the exception because of the value, but can't figure out what to do to fix it, as I'm sure it's relatively simple. Thanks for the help.
Edit 1:
Stacktrace:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException:
String index out of range: 0
at java.lang.String.charAt(Unknown Source)
at FractionTest.main(FractionTest.java:59)
It looks like you read empty line which returned you empty string "" so there is no characters there (not even 0th).
It usually happens when you are using nextLine right after other nextABC methods like nextInt since such methods doesn't consume line separators, and nextLine reads text until next line separator (or end of stream).
In that case you can add nextLine after that nextInt to consume line separator.
Anyway to avoid reading character from empty string and exception you can use something like
} while (input.toLowerCase().startsWith("y"));
instead of
input.length();//this actually doesn't change anything, you can remove it
repeat = input.charAt(0);
} while (repeat == 'Y' | repeat == 'y');
As #Phesmo mentioned you may be getting a 0-length line. This is an obscure problem. Have you called nextInt(), nextLong(), nextShort(), nextByte(), or nextBoolean() on the Scanner before calling nextLine()?
Try this
System.out.print("Do you wish to continue? (Y for yes / N for no)");
char ans;
do {
ans = keyboard.next().charAt(0);
// filter input
} while (ans == 'Y' || ans == 'y' || ans == 'N' || ans == 'n');
repeat = ans;
} while (repeat == 'Y' | repeat == 'y');
From documentation:
String Scanner#next()
Finds and returns the next complete token from this scanner. A complete token is preceded and followed by input that matches the delimiter pattern.
Or this
System.out.print("Do you wish to continue? (Y for yes / N for no)");
repeat = keyboard.next("[YyNn]").charAt(0);
} while (repeat == 'Y' | repeat == 'y');
From documentation:
String Scanner#next(String pattern)
Returns the next token if it matches the pattern constructed from the specified string.
"[YyNn]" is a character class pattern, it means match any character from the set.

Making a Y/N Condition work

I need help with a SIMPLE Y/N Condition for my program. I don't really get it to work as I want to.
Unfortunately all the other topics I find is very confusing. I'm a very novice student in programming.
I want a Y/N Condition that wont crash and is not CASE SENSITIVE. so if Y or y it goes back to another menu, if n and N is just stop the program and if anything else is typed in it will loop until the Y or N conditions are met.
This is what i wrote:
String input = ScanString.nextLine();
while (!"Y".equals(input) || !"y".equals(input) || !"N".equals(input) || !"n".equals(input)) {
System.out.println("Please enter Y/N (Not case sensitive): ");
input = ScanString.nextLine();
}
if ("Y".equals(input) || "y".equals(input)) {
meny1();
} else if ("N".equals(input) || "n".equals(input)) {
}
When it runs, whatever I put in, it won't break the while loop.
while (!"Y".equals(input) || !"y".equals(input) ||... means "keep looping while the input isn't 'Y' or the input isn't 'y' or...". By definition, one of those conditions will always be true.
The simplest way to do what you're looking for would be a case insensitive comparison, and an and (&&) rather than or operator:
while (!input.equalsIgnoreCase("Y") && !input.equalsIgnoreCase("N")) {
That means "keep looping while the input isn't 'Y' or 'y' and the input isn't 'N' or 'n'.
Or the same in Yoda-speak, since you were using Yoda-speak:
while (!"Y".equalsIgnoreCase(input) && !"N".equalsIgnoreCase(input)) {
Try this
while (!("Y".equalsIgnoreCase(input)) && !("N".equalsIgnoreCase(input))) {
}
Or
String[] validInputs = { "Y", "N" };
while(!Arrays.asList(validInputs).contains(input.toUpperCase())) {
}

How to make a x = y or z statement in Java

In my program, I have a String called yesOrNo that is a keyboard input. I created an if statement to test if yesOrNo is one of the following : "Y", "y", "Yes",
"yes" by using the || operator.
I got the error message: The operator || is undefined for the argument type(s) java.lang.String, java.lang.String. What is the right way to do something like this? Thanks.
Scanner keyboard = new Scanner(System.in);
String yesOrNo = keyboard.nextLine();
System.out.println(yesOrNo + "?" );
if (yesOrNo.equals("Y" || "y" || "Yes || "yes")){
The shortest I can think of is :
if (yesOrNo.equalsIgnoreCase("Y") || yesOrNo.equalsIgnoreCase("Yes"))
Your syntax is invalid. It needs to have separate clauses:
if(yesOrNo.equals("Y") || yesOrNo.equals("y")...)
or cleaner would be if you used regex:
if(yesOrNo.matches("Y|y|Yes|yes")) {
// Code.
}
Extra Reading
You should look at the String Docs. They detail all sorts of useful stuff.
Read up on Regex. It makes complex String comparison very simple.
Finally, look at the different Operators to see what kind of logical statements you can form, with the correct syntax.
Alternatively, you could create a list of acceptable answers and check whether the answer is in that list.
List<String> kindOfYes = Arrays.asList("yes", "y", "okay", "righto");
if (kindOfYes.contains(yesOrNo.toLowerCase())) { ...
Two ways:
Using equals:
if (yesOrNo.equals("Y") ||
yesOrNo.equals("y") ||
yesOrNo.equals("Yes") ||
yesOrNo.equals("yes")) {
//...
}
Using regexp (shorther than using || multiple times):
if (yesOrNo.toLowerCase().matches("y|yes")) {
//...
}
Try:
if(yesOrNo.equals("Y") || yesOrNo.equals("y")
|| yesOrNo.equals("Yes") || yesOrNo.equals("yes"))
if (yesOrNo.equals("Y") || yesOrNo.equals("y") || yesOrNo.equals("Yes") || yesOrNo.equals("yes"))
What about the next code?
String yesOrNo = keyboard.nextLine();
if (yesOrNo.toLowerCase().charAt(0) == 'y') {
//
}
NOTE: Do you think there's a quicker way? I think not.
Like this:
if (yesOrNo.equals("Y") || yesOrNo.equals("y") || yesOrNo.equals("Yes") || yesOrNo.equals("yes")){
//...
}
Your program syntax is wrong.
This is correct:
Scanner keyboard = new Scanner(System.in);
String yesOrNo = keyboard.nextLine();
System.out.println(yesOrNo + "?" );
if(yesOrNo.equals("Y") || yesOrNo.equals("y") || yesOrNo.equals("Yes") || yesOrNo.equals("yes")) {

Loop until valid input is reached [duplicate]

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed last year.
It executes correctly the first time, but:
It keeps printing "Please try again (Y/N)?" no matter what the
input is after asking to continue.
I am unsure if != is appropriate to use for String comparison. I want to say while
loopChoice "is not" Y or N, keep asking.
while(isLoop) {
// Ask for user input
System.out.print("Enter hours worked: ");
hoursWorked = scn.nextInt();
System.out.print("Enter rate per hour: ");
payRate = scn.nextInt();
scn.nextLine();
// Call functions to compute stuff
...
// Print results
...
System.out.print("\nDo you want to continue (Y/N)? ");
loopChoice = scn.nextLine().toUpperCase();
while(loopChoice != "Y" || loopChoice != "N") {
System.out.print("\nPlease try again (Y/N)? ");
loopChoice = scn.nextLine().toUpperCase();
}
switch(loopChoice) {
case "Y":
isLoop = true;
System.out.print("\n");
break;
case "N":
isLoop = false;
System.out.println("Terminating program...");
scn.close();
System.exit(0);
break;
default:
System.out.println("Your input is invalid!");
isLoop = false;
System.out.println("Terminating program...");
scn.close();
System.exit(0);
break;
}
}
You should compare with String equals
while (!loopChoice.equals("Y") && !loopChoice.equals("N"))
Also, replace the or operator with and operator
That's not how you compare strings in Java.
There is also a logical error in your code, as the string can't be both Y and N at the same time, you have to use && instead of ||. As long as the choice is neither Y or N, you want to continue the loop. If it is any of them, you want to stop. So && is the correct choice here.
To check if two strings are equal, you have to use .equals(obj)
while (!loopChoice.equals("Y") && !loopChoice.equals("N")) {
The reason for this is that == compares object references, and two Strings are most often not the same object reference. (Technically, they can be the same object reference, but that's not something you need to worry about now) To be safe, use .equals to compare Strings.
To avoid a possible NullPointerException in other situations, you can also use:
while (!"Y".equals(loopChoice) && !"N".equals(loopChoice)) {
You cannot use loopChoice != "Y", since "Y" is a String. Either use:
loopChoice != 'Y', or
"Y".equals(loopChoice)
Alternatively, use "Y".equalsIgnoreCase(loopChoice).
Case switching is also not possible for Strings if you use Java 1.6 or earlier. Be careful.
You need to know that OR Operation will return true if one of the two condition is true , so logically if you Enter Y , so you ask if the input is not equal Y so the answer is false then you will go to the next part in your condition if the input not equal N so the answer is True , so your finally result will be (True || False = True ) and then you will entered to while loop again
so the true condition is (the input not equal Y && not equal N)
You have fallen into the common early gap between checking equality of objects versus the values of objects. (You can see a quick list of string comparison information [here]
(http://docs.oracle.com/javase/tutorial/java/data/comparestrings.html)
What you wrote asks whether the object loopChoice is the same object as the string constant "Y" or the string constant "N" which will always return false. You want to ask whether the value of object loopChoice is the same as the value of string constant "Y".
You could rewrite your code as follows:
System.out.print("\nDo you want to continue (Y/N)? ");
// get value of next line, and trim whitespace in case use hit the spacebar
loopChoice = scn.nextLine().trim();
while (!("Y".equalsIgnoreCase(loopChoice) || "N".equalsIgnoreCase(loopChoice)) {
System.out.print("\nPlease try again (Y/N)? ");
loopChoice = scn.nextLine().toUpperCase();
}
Note, I like to put the constant value first for clarity. The general form for determining whether the value of two strings is the same is String1.equalsIgnoreCase(String2).

Categories