While loop just not working - java

I am just wanting some explanation (why) on why the following code is not working and a solution(How) to make the code run.
The goal of the program is to get a user input of a playing card, either J,Q,K,A, lower case or upper case. The program must only accept one of these values so it needs to validate the user input, displaying when its wrong and prompting till an accepted value is entered. The program then must take that user entered value and print the name of the playing card onto the console, Jack, Queen, King, Ace.
package practical_1;
import static java.lang.System.out;
import java.util.Scanner;
public class Question_4 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String Usr_Card;
out.print("Enter Card Letter Here.... ");
Usr_Card = input.next();
Usr_Card = Usr_Card.toUpperCase();
while (Usr_Card != "K" || Usr_Card != "Q" || Usr_Card != "J" || Usr_Card != "A"){
out.print("Invalid Input\nEnter Valid Card Letter Here: ");
Usr_Card = input.next();
Usr_Card = Usr_Card.toUpperCase();
}
switch (Usr_Card) {
case ("J"):
out.print("Jack");
break;
case ("Q"):
out.print("Queen");
break;
case ("K"):
out.print("King");
break;
case ("A"):
out.print("Ace");
break;
}
}
}

The OR operator || returns true if any section is true. In your example, if card is not K or not Q or not J or not A, continue the loop.
Let's break that down. User enters a "K"
Usr_Card != "K" // false
Usr_Card != "Q" // true
Usr_Card != "J" // true
Usr_Card != "A" // true
false || true || true || true === true // continue the loop
What we really want to check is whether the input is invalid. The input is invalid when it does not match at least one of K, Q, J, or A. Or better stated, when not K AND not Q and not J and not A.
We simply change our conditions from || to &&. Same example
Usr_Card != "K" // false
Usr_Card != "Q" // true
Usr_Card != "J" // true
Usr_Card != "A" // true
false && true && true && true === false // do not continue the loop
while (Usr_Card != "K" && Usr_Card != "Q" && Usr_Card != "J" && Usr_Card != "A")
Let's try an invalid example. Use enters an "A"
Usr_Card != "K" // true
Usr_Card != "Q" // true
Usr_Card != "J" // true
Usr_Card != "A" // true
true && true && true && true === true // continue the loop
So as you can see, we only continue the loop when we don't match any of the valid characters thanks to our AND && operation.
And as Scary Wombat has pointed out, you should not use == or != with strings. You should use .equals
while( !Usr_Card.equals("K") && !Usr_Card.equals("Q") && !Usr_Card.equals("J") && !Usr_Card.equals("A") )

This expression,
(Usr_Card != "K" || Usr_Card != "Q" || Usr_Card != "J" || Usr_Card != "A")
always evaluates to true, therefore the loop with never exit.
You need AND logic here, like:
(Usr_Card != "K" && Usr_Card != "Q" && Usr_Card != "J" && Usr_Card != "A")

Change the condition in the while loop to:
while (Usr_Card.equals("K") && Usr_Card.equals("Q") && Usr_Card.equal("J") && Usr_Card.equals("A"))
EDIT: As pointed out by #ScaryWombat in the comments, method of string comparison changed from '!=' to equals().

Related

Using || OR Operator within If Statements alongside characters

I'm very new to programming in general, and I'm having a bit of trouble with a program I'm writing in Java to help calculate my final grade in a class. This part of the program asks me what letter grade I would like to receive, and then determines if that input is valid. For example, if I typed into the keyboard that I wanted to receive a letter grade of "Z", because that is not a valid grade, I would like my program to output "Invalid Input" and exit. The code I have written below is not producing any syntax errors, but it outputs "Invalid Input" for every letter grade I choose, even A, B, and C (inputs that should be valid). Any help in understanding what's wrong is more than welcome.
Scanner input = new Scanner(System.in);
char desiredGrade
System.out.print("What letter grade do you want to achieve for the course? ");
desiredGrade = input.next().charAt(0);
if (desiredGrade != 'A' || desiredGrade != 'B' || desiredGrade != 'C'){
System.out.println("Invalid Input");
System.exit(0);
}
In addition to this, it would be helpful to not have to worry about case sensitivity with the inputs. I know I can use .ignoreCase() or .equalsIgnoreCase() with strings, but I'm not quite sure how to implement that with char.
see this Answer
For Upper- and Lowercase you can wrap your char in Character and then call toLowerCase and check the input and the expected value on Lowercase.
In your example
desiredGrade != 'A' || desiredGrade != 'B' || desiredGrade != 'C'
If you want to use the || operator you have to do it like that
if(!(desiredGrade == 'A' || desiredGrade == 'B' || desiredGrade == 'C')){
}
That way you check if the Input is A, B, or C and if not then exit
Lets say desiredGrade = 'A'
if (desiredGrade != 'A' || desiredGrade != 'B' || desiredGrade != 'C'){
The first condition will be false, but the second and third will be true. So
if (false || true || true)
Will result always in true.
The way to do it is using operator AND &&
if (desiredGrade != 'A' && desiredGrade != 'B' && desiredGrade != 'C'){
This way, if the user decides to input 'A' the operation will be
if (false && true && true){
Resulting in false. And if the user inputs 'Z', the operation will be
if (true && true && true){
That will result true and execute the Invalid input output.
EDIT
As it has been mentioned. The user may input 'a' (lowercase) for which condition desiredGrade = 'A' will be false since 'a' != 'A' (is not equal).
So it will be wise to convert desiredGrade to uppercase before the if statement.
Try out
(desiredGrade != 'A' && desiredGrade != 'B' && desiredGrade != 'C')
Basically, you want to check if desiredGrade is different than A and different than B and different than C, print out invalid input.
Try this:
if (! Arrays.asList ('A', 'B', 'C').contains (Character.toUpperCase (desiredGrade))) {
// your error handling
}

Why is this causing a constant 'true' in this while loop?

Here is the code;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Do you need instructions for this game? Y/N.");
char a = input.next().charAt(0);
// This while loop always comes out as true.
while (a != 'y' || a != 'n') {
System.out.println("Please enter either Y/N. ");
System.exit(0);
}
if (a == 'y') {
System.out.println("This game is called heads and tails.");
System.out.println("You must type h (heads), or t (tails).");
System.out.println("You will need to keep guessing correctly, each correct guess will increase your score.");
}
}
}
Is there an explanation on why it always comes out as true, and is there an alternative way of doing this? I want to have a validation check, where if the user inputs anything other than y, or n, the program shuts down.
The problem is, when I enter the character, y, or n, it shuts down anyway even though I'm using the != (not equals) operator.
If you have a==y, then a != 'n' is true and a != 'y' || a != 'n' is true.
If you have a==n, then a != 'y' is true and a != 'y' || a != 'n' is true.
If you have a == other thing, a != 'y' || a != 'n' is true.
It is everytime true with the OR operation. Need use AND.
(a != 'y' || a != 'n') at least one of the sub-conditions must be true.
Consider the three possible cases:
a is 'y': false || true gives true
a is 'n': true || false gives true
a is something else: true || true gives true
The character a cannot both be y and n, so the while loop is executed for any input.
Besides, the loop is not looping.
You're checking whether a is not equal to 'y' OR a is not equal to 'n'.
This is always true.
Change it into while ((a != 'y') && (a != 'n')).
The condition inside while in
while (a != 'y' || a != 'n')
is always true because
if a is equal to y, then a is obviously not equal to n. So, result is true.
And again, if a is equal to n, then a is obviously not equal to y. So, result is true.
And again, if a is not equal to y or n, then also the result is true.
So, the condition inside the while is always true. And for this reason, the execution is entering the while loop and after printing your message it is exiting.
So using AND instead of OR may solve your problem, like
while(a != 'y' && a !='n') {
//your work
}
And I think you willing to do this like below,
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Do you need instructions for this game? Y/N: ");
char a = input.next().charAt(0);
while (a != 'y') {
if(a =='n') {
System.exit(0);
}
else{
System.out.println("Please enter either Y/N : ");
a = input.next().charAt(0);
}
}
if (a == 'y') {
System.out.println("This game is called heads and tails.");
System.out.println("You must type h (heads), or t (tails).");
System.out.println("You will need to keep guessing correctly, each correct guess will increase your score.");
}
}
}
Your logic should be "a is not y and a is not n"
while (a != 'y' && a != 'n')

Java Passing a char from a method back to main

I'm writing a method that checks that 1 of 3 letters has been entered.
The problem is I can't get the method to return the char.
The char variable in initially read into Scanner and entered into an array.
Here is where it is read in,
//get house Type and send into array
System.out.println("Property " +numProperty+ " : Terraced, Semi-Detached, Detached: (T/S/D)");
houseType [i] = readLetter(input.next().charAt(0));
input.next().charAt(0);
And this is the method readLetter
public static char readLetter(char input){
if(input != 'T'||input != 't'||input != 'S'||input != 's'||input != 'D'||input != 'd')
System.out.println("Invalid input! Enter option T, S or D? ");
else
return input;
}
The error is
The method must return a result of type char.
Try this:
public static char readLetter(char input){
if(input != 'T'&& input != 't'&& input != 'S'&&input != 's'&&input != 'D'&&input != 'd')
{
System.out.println("Invalid input! Enter option T, S or D? ");
return 0; //or something that signals invalid input
}
else
{
return input;
}
}
In the readLetter method you must return value in both cases, for example:
public static char readLetter(char input) {
if(input != 'T' && input != 't' && input != 'S' && input != 's' && input != 'D' && input != 'd') {
System.out.println("Invalid input! Enter option T, S or D? ");
return 0;
} else {
return input;
}
}
This will return 0 if input != 'T' && input != 't' && input != 'S' && input != 's' && input != 'D' && input != 'd'. You need to handle that in your main method, something like this:
System.out.println("Property " +numProperty+ " : Terraced, Semi-Detached, Detached: (T/S/D)");
char ch = readLetter(input.next().charAt(0));
if ( ch != 0 ) {
// the input was valid
houseType[i] = readLetter(input.next().charAt(0));
}
input.next().charAt(0);
Update: as someone noticed your condition input != 'T'||input != 't'||input != 'S'||input != 's'||input != 'D'||input != 'd' will always return true (ie. your input will always be illegal) but the fix is to replace || into && (change ORs into ANDs).
I edited the code to reflect that.
You are missing the case when the user enters an invalid value.
What the method is supposed to return in this case?
IMO, this method should return true or false indicating wheter the passed input is valid(T,S or D) or not.
You are doing this:
if(input != 'T'||input != 't'||input != 'S'||input != 's'||input != 'D'||input != 'd')
System.out.println("Invalid input! Enter option T, S or D? ");
else
return input;
so since you are not using {}, then the code is returning only if the condition is not met.
so your compiler complains since that method is not always returning a char...

Java if and || issue

I'm doing this little program, but unfortunately I ran into this issue..
if (ccnString.charAt(0) != '4' || ccnString.charAt(0) != '3') {
System.out.println("The String entered does not fit any of the Credit card standards");
System.exit(0);
}
My program does not recognize if I put in any of the integers in my String.
However, if I delete my || and the last part, the if statement recognizes the first integer.
What am I missing here?
if (ccnString.charAt(0) != '4' || ccnString.charAt(0) != '3')
Is always true.
Every character is != '4' or != '3'
I guess you want && instead.
Details:
The statement A || B is true if A is true or B is true (or both are true).
In your example, lets say that the first character is '4'.
A = ccnString.charAt(0) != '4' is false (4 != 4 is false)
B = ccnString.charAt(0) != '3' is true (3 != 4 is true)
So A || B is true because B is true.
This is an addition to the many other answers that correctly state that you must use and (&&) instead of or (||).
You have been fooled by De Morgan's laws. They define how boolean expressions are negated.
In your example, the original expression that defines a valid user input is as follows:
validInput = userPressed3 or userPressed4
But as we are interested in invalid user input, this expression has to be negated:
not(validInput) = not(userPressed3 or userPressed4)
According to De Morgan, not(A or B) is equal to not(A) and not(B). So we can also write:
not(validInput) = not(userPressed3) and not(userPressed4)
In other words: It's De Morgan's fault! ;)
You probably want
if (ccnString.charAt(0) != '4' && ccnString.charAt(0) != '3') {
System.out.println("The String entered does not fit any of the Credit card standards");
System.exit(0);
}
This would give your error message only for Strings that don't start with 4 AND don't start with 3.
Your original condition gives an error for any String that either doesn't start with 4 OR doesn't start with 3, and since all Strings satisfy that condition, you'll always get your error message.
If you require additional conditions after the initial test, you can do :
if (ccnString.charAt(0) != '4' && ccnString.charAt(0) != '3') {
System.out.println("The String entered does not fit any of the Credit card standards");
System.exit(0);
} else if (ccnString.charAt(0) == '3' && ccnString.charAt(1) == '7') {
// here you know that ccnString starts with 37
} else if (...) {
...
}
... add as many else ifs as you need ...
else {
// default behavior if all previous conditions are false
}
It should be && not ||
ccnString.charAt(0) != '4' && ccnString.charAt(0) != '3'
Else (ccnString.charAt(0) != '4' || ccnString.charAt(0) != '3' always true
if ((ccnString.charAt(0) != '4' && ccnString.charAt(0) != '3')
|| (ccnString.charAt(0) == '3' && ccnString.charAt(1) == '7')) {
System.out.println("The String entered does not fit any of the Credit card standards");
System.exit(0);
}

JAVA if statements logic or syntax error? [duplicate]

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 8 years ago.
I getting the wrong result every time I run this program and I feel like an extra pair of eyes would be helpful at 4 in the morning. Can someone please help find where my curly braces or parentheses are off because I cannot find it for the life of me.
System.out.println("Please enter your guess") ;
userGuess = kbd.next() ;
if( userGuess != "a" || userGuess != "b" || userGuess != "c" ||
userGuess != "d" || userGuess != "e" || userGuess != "f" || userGuess != "g" ||
userGuess != "h" || userGuess != "i" || userGuess != "j" || userGuess != "k" ||
userGuess != "l" || userGuess != "m" || userGuess != "n" || userGuess != "o" ||
userGuess != "p" || userGuess != "q" || userGuess != "r" || userGuess != "s" ||
userGuess != "t" || userGuess != "u" || userGuess != "v" || userGuess != "w" ||
userGuess != "x" || userGuess != "y" || userGuess != "z" || userGuess!= "A" ||
userGuess != "B" || userGuess != "C" || userGuess != "D" || userGuess != "E" ||
userGuess != "F" || userGuess != "G" ||userGuess != "H" || userGuess != "I" ||
userGuess != "J" || userGuess != "K" ||userGuess != "L" || userGuess != "M" ||
userGuess != "N" || userGuess != "O" || userGuess != "P" || userGuess != "Q" ||
userGuess != "R" || userGuess != "S" || userGuess != "T" || userGuess != "U" ||
userGuess != "V" || userGuess != "W" || userGuess != "X" || userGuess != "Y" ||
userGuess != "Z" ) {
System.out.println("Invalid character, please enter your guess") ;
}userGuess = kbd.next() ;
Strings should be compared with the .equals() method and not ==.
That being said, in your case you might want to take a look at regular expressions, which would allow you to do a clean validation of the input. So in short:
//This code is untested, but it should guide you to what you need to do
Pattern userInput = Pattern.compile("^[A-Za-z]$"); //A-Z will match all the characters ranging from A to Z. a-z will do the same but it will check the lower case range. Alternatively, you could use ^[a-z]/i$ to make your regular expression case insensitive.
Scanner kbd = new Scanner(System.in);
String input = kbd.next();
Matcher matcher = userInput.matcher(input);
if(!matcher.matches())
{
System.out.println("Invalid character, please enter your guess") ;
}
You need to change == to equals to compare values of String (and any other object).
Also you have problem with logic, because userGuess != "a" || userGuess != "b" is true for all characters since if something is a then it is not b so one of these conditions will be always true.
You may want to change || to && or use proper tools like regex, or methods from Character class like Character.isLetter.

Categories