input character inside a while loop with validation - java

System.out.print("Enter the operator (+ - X /): ");
operator = input.next();
char c=operator.charAt(0);
while (c != '+' && c != '-' && c != '*' && c != '/'){
System.out.println("Operator doesn't match. Try again.");
System.out.print("Enter the operator (+ - X /): ");
input.next().charAt(0);
}
Here, I want an input character value from keyboard which will be only symbols just (+ - * /) inside a while loop. if the sign is not match the while loop will be running.
Here, the while loop is working but the character is not checked. So, while loop continuously works with-
System.out.println("Operator doesn't match. Try again.");
System.out.print("Enter the operator (+ - X /): ");

In the last line of your while loop, you are retrieving an user input, but not storing it anywhere. You should do like that:
c = input.next().charAt(0);
If you want to do something fancy, you could also try using the do-while loop, like below:
char c;
do {
System.out.println("Enter a operator (+ - * /):");
c = input.next().charAt(0);
} while(c != '+' && c != '-' && c != '*' && c != '/');

Related

How can I get the password to return back to password request if an invalid password is entered in Java?

I am trying to get the password to return and re-ask for the password if an invalid password is entered. And if a password is invalid 3 consecutive times, the system should terminate.
Is there an issue how I have structured the sequence of the lines of code? Please advise as I am rather new to Java.
public static void main(String []args){
final int MAX=10;
int invalidCount = 0;
final int MIN_Uppercase=1;
int uppercaseCounter=0;
int digitCounter=0;
int specialCounter=0;
System.out.println("Enter the password\n");
Scanner input = new Scanner(System.in);
String password = input.nextLine();
for (int i=0; i < password.length(); i++ ) {
char c = password.charAt(i);
if(Character.isDigit(c))
digitCounter++;
if(Character.isUpperCase(c))
uppercaseCounter++;
if(c == '!' || c == '#' || c == '#' || c == '$' || c == '%' || c == '^' || c == '&' || c == '*' || c == '(' || c == ')' || c == '-' || c == '_' || c == '=' || c == '+'){
specialCounter++;
}
}
if (password.length() >= MAX && uppercaseCounter >= 1 && specialCounter == 1 && (digitCounter == 2 || digitCounter == 3)) {
System.out.println("Valid Password");
}
else {
invalidCount++;
if(password.length() < MAX)
System.out.println("Enter atleast 10 characters");
if (uppercaseCounter < MIN_Uppercase)
System.out.println("Enter at least 1 uppercase character");
if(digitCounter != 2 && digitCounter != 3)
System.out.println("Enter either 2 or 3 digits only");
if(specialCounter != 1)
System.out.println("Password must contain 1 special character");
if (invalidCount == 3)
System.out.println("Maximum tries reached");
System.exit(invalidCount);
}
return;
}
You need to put this entire logic in a while loop that keeps tracks of invalidCount.
The other solution is to put the entire logic in a while loop which is always true and it breaks out of the loop in case correct password is entered.
Also, by seeing the if condition in your code, I would like to point out only the first println statement is inside the if part and not the second println statement.
if (invalidCount == 3)
System.out.println("Maximum tries reached");
System.exit(invalidCount);
but i think you wanted to put it something like this. such that when the count reaches 3, then it should terminate.
if (invalidCount == 3) {
System.out.println("Maximum tries reached");
System.exit(invalidCount);
}
Place the Password prompt into a while loop with a counter, for example:
Scanner userInput = new Scanner(System.in);
int maxPasswordAttempts = 3;
int passwordCounter = 0;
String password = "";
while (password.isEmpty()) {
passwordCounter++;
if (passwordCounter > maxPasswordAttempts) {
System.out.println("Maximum allowable password attempts (" + maxPasswordAttempts
+ ")has been\ncarried out! No longer accepting a passwords!");
System.exit(0);
}
System.out.print("Please enter a password (c to cancel): --> ");
password = userInput.nextLine().trim();
if (password.equalsIgnoreCase("c")) {
System.out.println("Password Entry - CANCELED!");
return;
}
/* Regex from the website:
https://mkyong.com/regular-expressions/how-to-validate-password-with-regular-expression/
Give it a read... */
if (!password.matches("^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[!##&()–[{}]:;',?/%*~$^+=<>]).{8,20}$")) {
System.out.println();
System.out.println("INVALID PASSWORD! - Secure Password requirements:\n" +
"-------------------------------------------------\n" +
"Password must contain at least one digit [0-9].\n" +
"Password must contain at least one lowercase Latin character [a-z].\n" +
"Password must contain at least one uppercase Latin character [A-Z].\n" +
"Password must contain at least one special character like: ! # # & ( ). %, etc.\n" +
"Password must contain a length of at least 8 characters and a maximum of 20 characters.\n" +
"Try Again...\n");
password = "";
}
}
System.out.println("\nYour VALID password is: " + password);
System.out.println("Now HASH it! :)");

Why is my program entering a while loop when the condition is false?

When I input a string operator whether it be addition(+), subtraction(-), multiplication(*), division(/) or module(%), it still enters the while loop even when I enter a valid input. I don't know what the problem could be because the while loop is working fine where I have to enter an int-value for variable num2.
import java.util.Scanner;
public class PolishNotationCalc {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int num1;
int num2;
String operator;
System.out.println("Polish notation calculator");
System.out.print("Please enter an operation(+, -, *, /, %) ");
operator = input.nextLine();
while (!operator.equals("+") || !operator.equals("-") || !operator.equals("*") || !operator.equals("/") || !operator.equals("%")) {
System.out.println("Please enter a valid operation ");
operator = input.nextLine();
if (operator.equals("+") || operator.equals("-") || operator.equals("*") || operator.equals("/") || operator.equals("%"))
break;
}
System.out.print("");
System.out.print("Please enter the first number ");
num1 = input.nextInt();
System.out.print("Please enter the second number ");
num2 = input.nextInt();
while (num2 == 0 && operator.equals("/")) {
System.out.println("Please pick a non zero number: ");
num2 = input.nextInt();
}
while (num2 == 0 && operator.equals("%")) {
System.out.println("Please pick a non zero number: ");
num2 = input.nextInt();
}
if (operator.equals("+"))
System.out.println(num1 + " + " + num2 + " = " + (num1 + num2));
else if (operator.equals("-"))
System.out.println(num1 + " - " + num2 + " = " + (num1 - num2));
else if (operator.equals("*"))
System.out.println(num1 + " * " + +num2 + " = " + (num1 * num2));
else if (operator.equals("/"))
System.out.println(num1 + " / " + num2 + " = " + (num1 / num2));
else if (operator.equals("%"))
System.out.println(num1 + " % " + num2 + " = " + (num1 % num2));
}
}
if you write your boolean selection in english it reads "While the operator does not equal "+" or it does not equal "-" or it does not equal "/" or it does not equal "*" or it does not equal "%" do the loop.
You need it to say "While the operator does not equal "+" AND it does not equal "-" AND it does not equal "/" AND it does not equal "*" AND it does not equal "%" do the loop.
Change || to && and it should work
For a while loop to be enacted all the parameters need to be true. So if one of the parameters is false, the while loop does not activate.
operator is always not equal to at least one of these strings: e.g. if it is equal to +, then it's not equal to -. If you combine one or more true conditions with ||, the overall result will be true.
You need to use && instead of ||, so that the loop breaks if any one of the conditions match:
while (!operator.equals("+") && !operator.equals("-") && ... ) {
You then don't need to check the value of operator again inside the loop; just let the new loop guard check it and break.
A more syntactically concise alternative would be to use a collection:
List<String> allowedOperators = Arrays.asList("+", "-", "*", "/", "%");
while (!allowedOperators.contains(operator)) {
System.out.println("Please enter a valid operation ");
operator = input.nextLine();
}
Similarly, when you are checking for num2 == 0:
List<String> zeroDenominatorOps = Arrays.asList("/", "%");
if (zeroDenominatorOps.contains(operator)) {
while (num2 == 0) {
// ...
}
}
while (!operator.equals("+") || !operator.equals("-") || !operator.equals("*") || !operator.equals("/") || !operator.equals("%")) {
System.out.println("Please enter a valid operation ");
operator = input.nextLine();
if (operator.equals("+") || operator.equals("-") || operator.equals("*") || operator.equals("/") || operator.equals("%"))
break;
}
For example when you enter "+" it becomes while(false || true|| true || true). so it always goes into while loop
You should substitute the || (or) with && (and)
SO
while (!operator.equals("+") || !operator.equals("-") || !operator.equals("*") || !operator.equals("/") || !operator.equals("%")) {
Becames
while (!operator.equals("+") && !operator.equals("-") && !operator.equals("*") && !operator.equals("/") && !operator.equals("%")) {
EDIT
You need an AND not an OR.
Lets say you input "+",which is a valid operator.
You'll enter the while because "+" NOT EQUALS "-", your second condition. This because the while conditions are in OR.
If you put these conditions in AND (&&), the "+" does not enter the while because one of the conditions is not true ( !operator.equals("+") )
Try this by changing ! to the whole parameters inside the while loop,It will start working
while (!(operator.equals("+") || operator.equals("-") || operator.equals("*") || operator.equals("/") || operator.equals("%"))) {
System.out.println("Please enter a valid operation ");
operator = input.nextLine();
if ((operator.equals("+") || operator.equals("-") || operator.equals("*") || operator.equals("/") || operator.equals("%")))
break;
}
It's simple math that sometimes people just forgets.
Lets simplify the cases.
1 OR x = 1;
1 AND x = x;
Lets be more concrete. Let we have some variable, A, B and C.
In the first case, OR, we have:
Which means that if at least one is true, the all expression is true. In you case having one operation that does not appear means that the loop must be true. Therefore, you should put something like this:
Which means not A AND not B AND not C.
I hope I have helped.
Have a nice day. :)
The loop condition has a different meaning than you thought. It's always true for any input string. It's the kind of condition that you will never have to write (hopefully).
To understand this better, let's first define when an operator can be accepted, in English:
An operator is accepted if it's one of the five operators: +, -, *, /, %
"One of" basically means "or". Therefore the corresponding code is
operator.equals("+") ||
operator.equals("-") ||
operator.equals("*") ||
operator.equals("/") ||
operator.equals("%")
And we can wrap it in a method:
private static boolean acceptable(String operator) {
return operator.equals("+") ||
operator.equals("-") ||
operator.equals("*") ||
operator.equals("/") ||
operator.equals("%");
}
Now the read-check-loop logic is very simple:
String operator;
do {
System.out.println("Please enter a valid operation ");
operator = input.nextLine();
} while (!acceptable(operator));
#SaclyrBarlonium, this is what I'm talking about. :P
Side Note
IMHO, every programmer should know De Morgan's laws so well that they can instinctively detect logical inconsistencies in the code. The inconsistency in this case is between the loop condition and the if statement in the loop body. If we put them side-by-side, we know that they are not equivalent, according to De Morgan's Law:
!operator.equals("+") || !operator.equals("-") || !operator.equals("*") || !operator.equals("/") || !operator.equals("%")
operator.equals("+") || operator.equals("-") || operator.equals("*") || operator.equals("/") || operator.equals("%")
But they should be equivalent, because the intent are the same: to continue the loop when the user entered a invalid operator and to terminate otherwise.

How to turn a user given String into Pig Latin?

Im trying to turn a string taken from the user into Pig Latin. I cannot use any special classes, methods, or arrays. I can only use a Scanner to create a object to take the string from the user and .length and .charAt, in addition to any type of looping. (Also cannot use switch statements or the break keyword)
Here is an example of what my output is suppose to be:
Enter a line of text: this is a test.
Input : this is a line of text.
Output: his-tay is-way a-way ine-lay of-way ext-tay.
Here is my code, I can only get my code to work with one word and it must have a space at the end. Only one loop works at a time depending on the loop. Im not sure what to do if I get an entire String.
I know that when the user enters a space that signals a new word, and when they enter a period, that signals the ending.
I had a hard time understanding your code. (It looks like you are trying to do it two ways at once?) Regardless, I believe I was able to understand your question. Here is a compilable and runnable example:
import java.util.Scanner;
public class PigLatin
{
public static void main(String[] args)
{
System.out.print("Enter a line of text: ");
Scanner keyboard = new Scanner(System.in);
String text = keyboard.nextLine();
System.out.println("\nInput: " + text);
System.out.print("Output: ");
if (text != null && text.length() > 0)
{
int i = 0;
// this iterates through the whole string, stopping at a period or
// the end of the string, whichever is closer
while (i < text.length() && text.charAt(i) != '.')
{
// these three variables only exist in this code block,
// so they will be re-initialized to these values
// each time this while loop is executed
char first = '\0'; // don't worry about this, I just use this value as a default initializer
boolean isFirst = true;
boolean firstIsVowel = false;
// each iteration of this while loop should be a word, since it
// stops iterating when a space is encountered
while (i < text.length()
&& text.charAt(i) != ' '
&& text.charAt(i) != '.')
{
// this is the first letter in this word
if (isFirst)
{
first = text.charAt(i);
// deal with words starting in vowels
if (first == 'a' || first == 'A' || first == 'e' || first == 'E'
|| first == 'i' || first == 'I' || first == 'o' || first == 'O'
|| first == 'u' || first == 'U')
{
System.out.print(first);
firstIsVowel = true;
}
// make sure we don't read another character as the first
// character in this word
isFirst = false;
}
else
{
System.out.print(text.charAt(i));
}
i++;
}
if (firstIsVowel)
{
System.out.print("-tay ");
}
else if (first != '\0')
{
System.out.print("-" + first + "ay ");
}
i++;
}
System.out.print('\n'); //for clean otuput
}
}
}
There are a few comments in there that might help guide you through my logic. This is almost definitely not the most efficient way to do this (even with your limitations), as I only whipped it up as a example of the type of logic you could use.
You could break it up into words, then process the current word when you hit a space or period:
System.out.print("Enter a line of text: ");
Scanner keyboard = new Scanner(System.in);
String text = keyboard.nextLine();
System.out.println("\nInput: " + text);
System.out.print("Output: ");
String curWord = "";
for (int i = 0; i < text.length(); i++) {
if (text.charAt(i) == ' ' || text.charAt(i) == '.') {
if (curWord.charAt(0) == 'a' || curWord.charAt(0) == 'e' ||
curWord.charAt(0) == 'i' || curWord.charAt(0) == 'o' ||
curWord.charAt(0) == 'u') {
System.out.print(curWord + "-way ");
} else {
for (int j = 1; j < curWord.length(); j++) {
System.out.print(curWord.charAt(j);
}
System.out.print("-" + curWord.charAt(0) + "ay ");
//System.out.print(curWord.substring(1)+"-"+curWord.charAt(0)+"ay ");
}
curWord = "";
} else {
curWord += text.charAt(i);
}
}

Key input restrictions

How do you restrict the letter being inputted;
for example I have the code
System.out.println("Enter a letter(A,B,C or D):");
letter = input.next().charAt(0);
How would I set up an if statement to say if letter does not equal "A" "B" "C" or "D", it will say please input correct letter?
thanks
I would recommend you to use a while loop, so it loops until you get a valid input:
Scanner input = new Scanner(System.in);
System.out.println("Enter a letter(A,B,C or D):");
char letter = input.next().charAt(0);
while (letter != 'A' && letter != 'B' && letter != 'C' && letter != 'D') {
System.out.println("Enter a valid letter(A,B,C or D):");
letter = input.next().charAt(0);
}
System.out.println(letter);
Output:
Enter a letter(A,B,C or D):
E
Enter a valid letter(A,B,C or D):
A
Valid: A
But if you just want an if conditional, use the same condition of the while above:
if (letter != 'A' && letter != 'B' && letter != 'C' && letter != 'D') {
...
}

Validate a string contains only certain characters in java

Ok, what I am trying to do is take a user input in infix notation and translate it to postfix and then evaluate it. I have that already completed.
What I am struggling with, is for the user input I need to validate that it only contains the following: (), 0-9, +, -, *, /, %
Each character will be separated by a space, so here is a potential valid input:
( 3 + 4 ) * 5 / ( 6 - 7 )
I have created an InvalidCharacterException that I wish to throw if the user string contains anything other than those characters.
Here is what an invalid input would look like:
3 - 5 ^ 5
The ^ would be an invalid character and then I would throw new InvalidCharacterException and ask for a new input.
I will also say I have looked at a ton of regex samples, and to be honest I don't understand what they're doing.
EDIT:
Ok, this is what I ended up implementing because I don't really understand anything else. Any advice on a simpler way?
for(int i = 0; i <= infix.length(); i++){
if(infix.charAt(i) == '(' || infix.charAt(i) == ')' || infix.charAt(i) =='+'
|| infix.charAt(i) =='-' ||infix.charAt(i) == '*' ||infix.charAt(i) == '/'
||infix.charAt(i) == '%' ||infix.charAt(i) ==' ' ||infix.charAt(i) == '0'
||infix.charAt(i) == '1' || infix.charAt(i) =='2' || infix.charAt(i) =='3'
||infix.charAt(i) == '4' ||infix.charAt(i) == '5' ||infix.charAt(i) == '6'
||infix.charAt(i) == '7' || infix.charAt(i) =='8' ||infix.charAt(i) == '9'){
}else{
throw new InvalidCharacterException(infix.charAt(i));
}
}
Infix is the variable name of my user input as a StringBuffer.
You can use a Scanner to validate your string:
Scanner scanner = new Scanner(string);
String validationResult = scanner.findInLine("[^0-9()+\\-*\\/%]+");
if (validationResult != null) {
// Invalid character found.
throw new InvalidCharacterException("Invalid character: " + validationResult);
}
The findInLine method returns a String with the characters that match the regex and the regex looks for any character not valid in your validation. The findInLine only returns a non null String when there are any invalid characters in the String.
I would suggest you use a Scanner (for an example) and then loop over each character (in each token) and throw your Exception if your criteria are met (e.g. look at Character.isDigit) or just write your own method to test against acceptable characters (e.g. is char is contained in"()0123456789+-*/%").
In your code this is probably better because it does the same thing.
Btw it probably should be i < infix.length() not <=
for(int i = 0; i < infix.length(); i++){
char x = infix.charAt(i);
if(!(Character.isDigit(x) || x == '/' || x == '*' ||
x == '+'|| x== '-' || x=='%' || x == '\n'))
throw new InvalidCharacterException(x);
/* what you want to do if valid*/
}

Categories

Resources