My program should output ‘What is your name?’ only if “hi” and “hello” are typed, but it still outputs ‘What is your name?’ even if I type a number or a single character… I’m so frustrated. Can someone help me out with this? I think it has something to do with the !phrase.equals statement…
import java.util.Scanner;
public class prog2 {
public static void main(String[] args)throws Exception {
String phrase;
String name;
char Letter;
Scanner keyboard = new Scanner(System.in);
System.out.print("Type a phrase: ");
phrase = keyboard.nextLine();
if(!phrase.equals("hi") || !phrase.equals("hello")){
System.out.print("What is your name?");
Scanner keyboard1 = new Scanner(System.in);
name = keyboard1.nextLine();
System.out.print("Your name is" +name);
}else{
Scanner keyboard2 = new Scanner(System.in);
System.out.print("Type a Letter: ");
Letter = (char) System.in.read();
System.in.read();
System.out.print("Your letter is "+ Letter);
}
}
You condition !phrase.equals("hi") || !phrase.equals("hello") is always true.
If the word is hi, it's false or true; if the word is hello, it's true or false. Otherwise its true or true. You did not describe the intended behaviour, thus I can't tell what is correct.
It's not doing what you wanted to do. Check De Morgan laws.
You probably want to do:
if(!(phrase.equals("hi") || phrase.equals("hello")))
Which is not like what you did because if(!a || !b) is not like if(!(a || b)).
Try :
if(phrase.equals("hi") || phrase.equals("hello")) {
//rest of your code
}
Related
I have the following code, which continues to ask the user to enter a letter as long as the letter is either "a" or "b":
import java.util.Scanner;
public class Main
{
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
String letter;
System.out.print("Enter a letter: ");
letter = scan.nextLine();
while(letter.equals("a") || letter.equals("b"))
{
System.out.println("You entered: " + letter);
System.out.print("Enter a letter: ");
letter = scan.nextLine();
}
}
}
But the following code is repeated twice:
System.out.print("Enter a letter: ");
letter = scan.nextLine();
Is there a way to make the above code only appear one time?
while (true) {
System.out.print("Enter a letter: ");
String letter = scan.nextLine();
if (!letter.equals("a") && !letter.equals("b"))
break;
System.out.println("You entered: " + letter);
}
This is the classic example of a loop that is neither naturally while-do nor do-while — it needs to exit from the middle, if you want the same behavior and also to reduce code duplication.
(Notice also that the variable declaration letter has been moved to an inner scope since it is no longer needed in the outer scope. This is a small positive indication.)
As an alternative to while (true) some languages allow degenerate for-loop as in for(;;).
The below reverses the logic of the conditional loop exit test, at the expense of more control flow logic.
while (true) {
System.out.print("Enter a letter: ");
String letter = scan.nextLine();
if (letter.equals("a") || letter.equals("b")) {
System.out.println("You entered: " + letter);
continue;
}
break;
}
(There is no difference between these in efficiency terms — these are equivalent at the level of machine code.)
do while loop
import java.util.Scanner;
public class Main
{
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
String letter;
do{
System.out.print("Enter a letter: ");
letter = scan.nextLine();
System.out.println("You entered: " + letter);
}while(letter.equals("a") || letter.equals("b"));
}
}
It will loop once first, and then continue again if the statment is true.
You need to perform three sequential actions in a loop:
read the input entered by the user;
validate the input;
print the input, but only if it is valid.
That means that conditional logic must reside inside the loop before the statement that prints the input. And that makes the condition of the loop redundant. Instead, we can create an infinite loop with a break statement wrapped by a condition, that validates the input.
While loop
That's how it can be done using a while loop:
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String letter;
while (true) {
System.out.print("Enter a letter: ");
letter = scan.nextLine();
if (!letter.matches("[ab]")) break;
System.out.println("You entered: " + letter);
}
}
Method matches() that expects a regular expression as argument is used in the code above to simplify the termination condition.
For more information on regular expressions, take a look at this tutorial
For loop
Regarding the advice of utilizing a for loop - that's doable, but by its nature the task of reading the user input fits better in the concept of while loop because we don't know the amount of data in advance, and the iteration can terminate at any point in time.
Also note syntax of the for statement consists of three parts separated with a semicolon:
initialization expression - allow to define and initialize variables that would be used in the loop;
termination expression - condition which terminates the execution of the loop;
increment expression - defines how variables would change at each iteration step.
All these parts are optional, but the two semicolons ; inside the parentheses always have to be present.
Because as I've said earlier, the input needs to be validated inside the loop, we can't take advantage from the termination expression and increment expression.
For the sake of completeness, below I've provided the version of how it can be achieved using a for loop:
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
for (String letter = "a"; ;) {
System.out.print("Enter a letter: ");
letter = scan.nextLine();
if (!letter.matches("[ab]")) break;
System.out.println("You entered: " + letter);
}
}
The only advantage is that the scope of the variable letter was reduced. But approach of utilizing while loop is more readable and expressive.
Alternative approach
Another option is to preserve your initial structure of the code:
initialize the variable letter before the loop, at the same line where it is defined;
enter the loop if letter holds a valid input;
print the input and reassign the variable.
But in order to avoid duplication of the code line responsible for printing the prompt and reading the input will be extracted into a separate method.
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String letter = readInput(scan);
while (letter.matches("[ab]")) {
System.out.println("You entered: " + letter);
letter = readInput(scan);
}
}
public static String readInput(Scanner scan) {
System.out.print("Enter a letter: ");
return scan.nextLine();
}
As Bobulous mentioned, a do-while loop is another simple solution. If duplicating the conditional is still a deal-breaker for you, though, you can also create a function that returns a boolean, and, when true, prints the extra text.
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
String letter;
do
{
System.out.print("Enter a letter: ");
letter = scan.nextLine();
} while(inputIsAOrB(letter));
}
public static boolean inputIsAOrB(String input) {
if (input.equals("a") || input.equals("b"))
{
System.out.println("You entered: " + input);
return true;
}
else
{
return false;
}
}
A while loop with a break after executing your second print command will limit the code to only asking for a single input.
Scanner ct = new Scanner(System.in);
String input;
System.out.print("Please enter either 'a' or 'b': ");
input = ct.nextLine();
while(input.equals("a") || input.equals("b")){
System.out.println("You entered: " + input);
break;
}
You can also view the problem as generating and processing a stream of strings. The side effects in the generator may trigger some philosophical discussions, otherwise I think it is quite clean:
Stream.generate(() -> {
System.out.print("Enter a letter: ");
return scan.nextLine();
})
.takeWhile(str -> str.equals("a") || str.equals("b"))
.forEach(str -> System.out.println("You entered: " + str));
... which will run like this:
Enter a letter: a
You entered: a
Enter a letter: b
You entered: b
Enter a letter: c
Process finished with exit code 0
Simply
List<Character> expectedChars = new ArrayList<>();
expectedChars.add('a');
expectedChars.add('b');
while(!expectedChars.contains(line = scan.nextLine())) {
System.out.println("Not expected");
}
// Now has a expected char. Proceed.
I without using any break or if-else externally (I am using ternary operator though) within control loop, you can also use below :
Scanner scanner = new Scanner(System.in);
boolean flag=true;
while (flag) {
System.out.println("enter letter");
String bv = scanner.nextLine();
flag=bv.matches("a|b");
System.out.println(flag?"you entered"+bv:' ');
}
with for loop, it can be even simpler :
Scanner scanner = new Scanner(System.in);
for (boolean flag = true; flag;) {
System.out.println("enter letter");
String bv = scanner.nextLine();
flag = bv.matches("a|b");
System.out.println(flag ? "you entered" + bv : ' ');
}
Or if you ok for having whitspace for first run:
Scanner scanner = new Scanner(System.in);
String aa=" ";
String bv=null;
for (boolean flag = true; flag;aa=(flag?"you entered: "+bv:" ")) {
System.out.println(aa);
System.out.println("enter letter");
bv = scanner.nextLine();
flag = bv.matches("a|b");
}
You can easily run a while loop until letter = "a" or letter = "b". Code will start the while loop with intial "" value of the letter and get the new value by scanner. Then it check the new value of the letter before starting the next round of the loop.
package com.company;
import java.util.Scanner;
public class Main
{
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
String letter = "";
while(!(letter.equals("a") || letter.equals("b")))
{
System.out.print("Enter a letter: ");
letter = scan.nextLine();
System.out.println("You entered: " + letter);
}
}
}
Similar as previous answer, but from a code readability perspective i would create an array of valid characters instead and use in condition. That results in the more "text like" condition below reading "if not validCharacters contains letter":
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
List<String> validCharacters = List.of("a", "b");
while (true) {
System.out.print("Enter a letter: ");
String letter = scan.nextLine();
if (!validCharacters.contains(letter)) {
break;
}
System.out.println("You entered: " + letter);
}
}
Your code just needed a little tweak to make it work, although you can use many more efficient approaches but here it is:
import java.util.Scanner;
public class Main
{
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
String letter = "a";
while(letter.equals("a") || letter.equals("b"))
{
System.out.print("Enter a letter: ");
letter = scan.nextLine();
System.out.println("You entered: " + letter);
}
}
}
My Computer Science class assignment requires that I write a program which determines if a word or phrase is a palindrome (is the same forward and backwards, ie "noon"). As part of this, I have to write a method which removes all punctuation and spaces, so they are not counted in determining if it is a palindrome. It also runs on a loop, allowing the user to input as many phrases they want until they indicate they're done. My problem is that when the word/phrase entered contains a space, somehow it terminates the loop and doesn't allow more input. The program works just fine, as long as the input has no spaces. Here's my code:
In class RecursivePalindrome:
public String removePunctuation(String s){
s = s.replaceAll("\\.","");
s = s.replaceAll("!","");
s = s.replaceAll(",","");
s = s.replaceAll(" ","");
s = s.replaceAll("'","");
s = s.replaceAll("-","");
s = s.replaceAll("\\?","");
return s;
}
public boolean isPalindrome(String s) {
s = removePunctuation(s);
String firstChar = s.substring(0,1);
String lastChar = s.substring(s.length()-1);
if (s.length() == 1){
return true;
}
if (s.length() == 2 && firstChar.equalsIgnoreCase(lastChar)){
return true;
}
if (!firstChar.equalsIgnoreCase(lastChar)){
return false;
}
return isPalindrome(s.substring(1, s.length() - 1));
}
In class RecursivePalindromeTester:
public static void main(String[]args){
//Create objects
Scanner in = new Scanner(System.in);
RecursivePalindrome palindrome = new RecursivePalindrome();
//Output
for (String again = "Y"; again.equalsIgnoreCase("Y"); again = in.next())
{
//Prompt for input
System.out.println();
System.out.print("Enter a word or phrase: ");
String phrase = in.next();
//Output
if (palindrome.isPalindrome(phrase)){
System.out.println("This is a palindrome.");
}
else
System.out.println("This is not a palindrome.");
System.out.print("Another word or phrase? (Y/N): ");
}
}
The output should be:
"Enter word or phrase: <input>mom- mom!
This is a palindrome
Another word or phrase? (Y/N): <input>Y
Enter a word or phrase: <input>Dog?
This is not a palindrome
Another word or phrase? (Y/N): <input>N"
Terminate
But instead I get:
"Enter word or phrase: <input>mom- mom!
This is a palindrome
Another word or phrase? (Y/N):"
Terminate
I really have no idea why a space would cause the loop to terminate, especially since it doesn't do this with any other punctuation.
Totally agreed with #Ilya Bursov comment,
You should use in.nextLine() instead of in.next() , there are big difference between both methods
next() can read the input only till the space. It can't read two words separated by a space. Also, next() places the cursor in the same line after reading the input.
nextLine() reads input including space between the words (that is, it reads till the end of line \n). Once the input is read, nextLine() positions the cursor in the next line
Try like this ,
class RecursivePalindromeTester {
public static void main(String[] args) {
//Create objects
Scanner in = new Scanner(System.in);
RecursivePalindrome palindrome = new RecursivePalindrome();
//Output
for (String again = "Y"; again.equalsIgnoreCase("Y"); again = in.nextLine()) {
//Prompt for input
System.out.println();
System.out.print("Enter a word or phrase: ");
String phrase = in.nextLine();
//Output
if (palindrome.isPalindrome(phrase)) {
System.out.println("This is a palindrome.");
}
else
System.out.println("This is not a palindrome.");
System.out.print("Another word or phrase? (Y/N): ");
}
}
}
I wrote a simple if / else that is supposed to print the answer to the if else. but does not respond even with the correct input. I can't see what I'm missing.
import java.util.Scanner;
public class MarriageQuiz{
public static void main(String[] args){
Scanner input = new Scanner(System.in);
String marStat;
System.out.print("Please enter your Marital Status (M or S) >> ");
marStat = input.nextLine();
marStat = marStat.toUppercase();
if(marStat.equals('M')){
System.out.print("You are married");
}
else if(marStat.equals('S')){
System.out.print("You are single");
}
}
}
Your code is comparing a String object against a character literal, which I believe the JVM will box into a Character object. Well, these two objects don't belong to the same class, so "M".equals('M') will return false. To remedy this, use "M".equals("M").
change toUppercase() to toUpperCase() and marStat.equals('M') to marStat.equals("M") also marStat.equals('S') to marStat.equals("S")
import java.util.Scanner;
public class MarriageQuiz {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String marStat = "";
System.out.print("Please enter your Marital Status (M or S) >> ");
marStat = input.nextLine();
marStat = marStat.toUpperCase();
if (marStat.equals("M")) {
System.out.print("You are married");
} else if (marStat.equals("S")) {
System.out.print("You are single");
}
}
}
On the other hand, you can use Character type instead of 'String'. Rather using Character would be more accurate as you are dealing with only one character.
Scanner input = new Scanner(System.in);
Character marStat;
System.out.print("Please enter your Marital Status (M or S) >> ");
marStat = input.next().charAt(0);
marStat = Character.toUpperCase(marStat);
if (marStat.equals('M')) {
System.out.println("You are married");
} else if (marStat.equals('S')) {
System.out.println("You are single");
}
use ""
if(marStat.equals("M")){
System.out.print("You are married");
}
else if(marStat.equals("S")){
System.out.print("You are single");
}
As mentioned in a comment above, you are comparing a String object to an autoboxed Character object. One fix is obviously using double quotes, which Java will autobox to a String object your code will work.
A few tips to save a few lines of code: use String.equalsIgnoreCase() to save a line converting the incoming string to uppercase.
Next, consider using a constant for marital status:
public class MarriageQuiz{
private static final String STATUS_MARRIED = "M";
...
if (marStat.equalsIgnoreCase(STATUS_MARRIED)) {
...
That way you can use STATUS_MARRIED all over your code but can change it from, say, "M" to "Married" easily.
So I just started learning Java, its literally like my 1st day and I wanted to try to make a coinflip game. I already know a decent amount of Javascript and so i was trying to apply that knowledge to java. So everything has been working so far except one thing: Prompting a user for a choice. So read online that i have to import a scanner so i did that as you can see from my code. I also tried some code where you can have the user import a string but you can see a bit later in my program i change the variable userChoice into a number. So basically i just need help with this. If there is some way to have a variable type that can store both numbers or strings that would be best. But im tottaly open to other ways of doing this! Thanks in advanced! Here is the code:
package test;
import java.util.Scanner;
public class testclass {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("hi");
int bob;
bob = (int) Math.floor(Math.random()*2);
System.out.println(bob);
System.out.println("Enter heads or tails?");
System.out.println("You entered "+ userChoice);
if (bob == 0) {
System.out.println("Computer flipped heads");
}
else {
System.out.println("Computer flipped tails");
}
if(userChoice == "Heads") {
userChoice = 0;
}
else {
userChoice = 1;
}
if (userChoice == bob) {
System.out.println("You win!");
}
else {
System.out.println("Sorry you lost!")
}
}
}
Use a scanner, as you said:
Scanner in = new Scanner(System.in);
Then, prompt the user to enter something in:
String userChoice = in.nextLine();
Also, when you compared strings:
if(userChoice == "Heads") {...
that's bad to do for none-primitive objects. It's best to only use the == to compare values that are ints or enums. If you compare a String like this, it won't work, because it's checking if the objects are the same. Instead, compare like this:
if(userChoice.equals("Heads")) {...
Also, to convert to an int (NOTE: You can't convert one type of object to another that aren't related in any way! You'll have to create a new object if you're wanting to do that), do this:
int myInt = Integer.parseInt(myString); // NOTE: Can throw NumberFormatException if non-number character is found.
So your program should look somewhat like:
package test;
import java.util.Scanner;
public class testclass {
public static void main(String[] args) {
//System.out.println("hi");
Scanner in = new Scanner(System.in);
int bob;
int userChoice;
String input;
bob = (int) Math.floor(Math.random()*2);
System.out.println(bob);
System.out.println("Enter heads or tails?");
input = in.nextLine(); // waits for user to press enter.
System.out.println("You entered "+ input);
if (bob == 0) {
System.out.println("Computer flipped heads");
}
else {
System.out.println("Computer flipped tails");
}
if(input.equals("Heads")) {
userChoice = 0;
}
else {
userChoice = 1;
}
if (userChoice == bob) {
System.out.println("You win!");
}
else {
System.out.println("Sorry you lost!");
}
in.close(); // IMPORTANT to prevent memory leaks
}
}
You've already imported the Scanner class so you can now create a variable of the type Scanner for taking inputs.
Scanner in = new Scanner();
userChoice = in.nextLine();
nextLine() can be used to input a character or a string from the user.
To convert the string into a integer, You can assign the integer value to the string in the following way.
if(userChoice == "Heads") {
userChoice = "" + 0;
}
else {
userChoice = "" + 1;
}
"String" datatype in Java can hold both numbers and strings (as you asked). You can get user input using Scanner utility as below:
Scanner input = new Scanner();
userChoice = input.nextLine(); // if it is a string
//userChoice = input.nextInt(); // if it's integer choice
If your string is an integer then you can also parse it to get its integer value. For parsing:
int value = Integer.parseInt(userChoice);
Also for comparing String values you should use "equals" function rather than "==".
if(userChoice.equals("Heads")){...} //rather than if(userChoice == "Heads"){...}
Having imported java.util.Scanner, to get input from the user as a String, create a Scanner object that parameterizes System.in and assign userChoice the value of nextLine() invoked by the Scanner object:
Scanner input = new Scanner(System.in);
String userChoice = input.nextLine();
A few things about your code. The relational operator, ==, is used for comparing primitive data - not objects. Use string1.equals(string2) to see if two strings are equal.
Also, bob = (int) Math.floor(Math.random()*2); is really bob = (int)(Math.random() * 2);
because casting a double as an integer truncates the double to the highest integer less than or equal to it.
It might help you to get the ideas.
public static void main(String[] args) {
Random rd = new Random();
//Enter 1 0R 0
int bob = rd.nextInt(2);
String userChoice;
Scanner sc = new Scanner(System.in);
System.out.println("Please enter a number");
userChoice = sc.nextLine();
System.out.println("You entered " + userChoice + " and bob is " + bob);
int uc = Integer.parseInt(userChoice);
if (uc == bob) {
System.out.println("Hehe");
} else {
System.out.println("Sorry");
}
}
i'm taring convert this to a Java program :
$ java SpaceTravel
Welcome to the SpaceTravel agency
What do you want do? [h for help]
a
Unknown command. Type h for help
What do you want do? [h for help]
h
h: print this help screen
q: quit the program
What do you want do? [h for help]
q
Bye bye!
Now the problem that my program seem's do an infinite loop at the 2nd do while loop whatever is my choice i tried many algorithm's and steel wont work for me . here is my code :
package gesitionEleve;
import java.util.Scanner;
public class SpaceTravel {
public static void main(String[] args) {
System.out.print("Welcom to the SpaceTravel Agency\n");
int lafin = 0;
while (lafin != 1) {
int taill;
do {
System.out.print("What do you want to do [h for help] : ");
Scanner sc = new Scanner(System.in);
String test = sc.nextLine();
taill = test.length();
} while(taill == 0);
char choix = 0;
String test;
if (choix != 'h') {
do {
System.out.print("\nUknown command. Type h for help ");
System.out.print("\nWhat do you want to do : ");
Scanner sc1 = new Scanner(System.in);
test = sc1.nextLine();
choix = test.charAt(0);
} while(choix == 'h');
}
System.out.print("\nh : print this help page ");
System.out.print("\nq : quite the program ");
do {
Scanner sc1 = new Scanner(System.in);
test = sc1.nextLine();
choix = test.charAt(0);
switch(choix) {
case 'h' :
System.out.print("\nh : print this help page ");
System.out.print("\nq : quite the program ");
case 'q' :
System.out.print("Bye bye");
lafin++;
}
} while (choix == 'q' || choix == 'h');
}
}
}
The below program suits your needs:
import java.util.Scanner;
public class SpaceTravel
{
public static void main(String[] args) {
System.out.print("Welcome to the SpaceTravel Agency\n");
String str; //To avoid exception when user enters just an enter
while (true) { //infinite loop
char choix; //for getting a character
System.out.print("What do you want to do [h for help] : ");
Scanner sc = new Scanner(System.in);
str=sc.nextLine(); //get input
if(str.length()!=1) //If no characters or more than one character is entered,
{
System.out.println("Invalid Choice");
continue;
}
choix=str.charAt(0); //get char from str
if(choix=='q') //if char is q,break out of the while loop
break;
if (choix != 'h') { //if char is not h,print invalid input and continue the loop
System.out.println("\nUnknown command. Type h for help ");
continue;
}
System.out.print("\nh : print this help page ");
System.out.print("\nq : quit the program ");
}
}
}
You got the condition of that loop backwards.
If you want to leave the loop when 'h' is entered, it should be :
do {
System.out.print("\nUknown command. Type h for help ");
System.out.print("\nWhat do you want to do : ");
Scanner sc1 = new Scanner(System.in);
test = sc1.nextLine();
choix = test.charAt(0);
} while(choix != 'h');
Currently you are staying in the loop as long as 'h' is entered.
You should also note that test.charAt(0) would throw an exception if the user presses enter without typing any characters.