I am beginning to learn Java and trying the while loop, I have written a simple program as a simple guessing game where the user tries to guess a letter between A and Z and the computer will print "correct" and repeats if the guessed letter is wrong, however, every time I try to run it the output is three iterations by default, I have tried to change the while loop to do-while and got the same output, I even added the int variable i as a counter to see if its really doing 3 iterations and the value of i always comes as 4 (3 wrong iterations when really it should be 1 plus one when I enter the correct answer).
Can you tell me what is the mistake I am doing?
class Guess {
public static void main (String[] args) throws java.io.IOException {
char answer = 'K', ignore, ch = 'a';
int i=0;
while (ch != 'K') {
System.out.println("I am Thinking of a letter between A and Z, can you guess it?");
ch = (char) System.in.read();
if (ch !='K')
System.out.println("Wrong ! please try again");
i++;
}
System.out.println("Correct!, you guessed after "+i+" attempts");
}
}
The issue is, when you press Enter after typing the character in the console, the loop is executing once for the entered character and again once for the newline which is 10.
So I just edited your code to skip the new line and wait for the next character to be entered, Also I moved the initial prompt outside of the loop. I hope this code would fix your issue:
public static void main(String[] args) throws IOException {
char answer = 'K', ignore, ch = 'a';
int i = 0;
System.out.println("I am Thinking of a letter between A and Z, can you guess it?");
while (ch != 'K') {
ch = (char) System.in.read();
if(!Character.isLetter(ch)){
continue;
}
System.out.println("Wrong ! please try again");
i++;
}
System.out.println("Correct!, you guessed after " + i + " attempts");
}
This is how it should look like.
Your code just missed the else block which is very necessary to break out of the loop,when the user guess the right character.I have added one.
class guess {
public static void main (String[] args) throws java.io.IOException {
char answer = 'K', ignore,ch='a';
int i=0;
while (ch != answer) {
System.out.println("I am Thinking of a letter between A and Z, can you guess it?");
ch = (char) System.in.read();
i++;
if (ch !=answer) {
System.out.println("Wrong ! please try again");
}
else{
System.out.println("Correct!, you guessed after "+i+" attempts");
break;
}
}
}
}
Hi there I got a tip for you.
I personally would use a Scanner instead of System.in.read. A Scanner is an object that reads an input.
To create one, simply tipe this:
Scanner sc = new Scanner(System.in); //System.in referes to a console input
To know what the user typed use sc.nextLine();, which returns, as I said, the input. However it returns a String, not a char. So, in this case, you also needed to change the type of 'ch'.
To compare the answers with the input you will need to used the method equals(). Basically, if two things are the same, it returns true.
That said, your code should look like this:
Scanner sc = new Scanner(System.in);
String answer = "K",ch;
int i=0;
boolean correct = false;
while (!correct) {
System.out.println("I am Thinking of a letter between A and Z, can you guess it?");
ch = sc.nextLine();
i++;
if (!ch.toUpperCase().equals(answer)) { // or ch.equals(answer) == false
System.out.println("Wrong ! please try again");
}else{ //if they are the same
correct = true; //the answer is correct so you can leave the while loop
System.out.println("Correct!, you guessed after "+i+" attempts");
}
}
sc.close(); //you should always close a scanner after you use it, but you can ignore this step for now
Note that I also used a method called toUpperCase(). That method transform all the characters of the string to upper case, so, even if you type "k" instead of "K" you would also quit the loop.
Related
I am creating code that translated a word (obtained by the user) into Pig Latin. My code is working really good, except for one thing. I want the user to type in "y" or "n" to determine if the code will be run or not. I am using a while loop to determine what to execute. If a user types anything but the two listed above, I want it to ask again. At the moment I have a placeholder that calls the user silly and to restart the code. How can I accomplish this? Thanks a ton everyone!
public static void main(String[] args)
{
Scanner stdIn = new Scanner(System.in);
String playGame;
String word;
// Explains what the program does \\
System.out.println("Welcome to Coulter's Pig Latin Translator!");
System.out.println("If you choose to play, you will be asked to type a word which will be translated.");
System.out.println();
// Asks the user if they would like to play and checks 'y' or 'n' using a while statement \\
System.out.println("Would you like to play? [y/n]: ");
playGame = stdIn.next();
while(playGame.equals("y") || playGame.equals("n")) // While expression that will check if the user enters a 'y' or 'n'
{
if (playGame.equals("y")) // Executes if the user entered 'y'
{
System.out.println("Please enter the word that you would like to translate: ");
word = stdIn.next(); // Receives the word the user wishes to translate
System.out.println("_______________________________________________________");
System.out.println();
System.out.println("You entered the word: " + word); // Displays what the user entered
System.out.println();
System.out.println("Translation: " + solve(word)); // Displays the solved word
System.out.println();
System.out.println("Thanks for playing!"); //
return; // Ends the code
}
else if(playGame.contentEquals("n")) // Executes if the user entered 'n'
{
System.out.println("That's okay! Come back when you want to.");
return; // Ends the code
}
}
System.out.println("_______________________________________________________");
System.out.println("Don't be silly. Restart and type either 'y' or 'n'"); // Tells the user to restart if they entered anything but 'y' or 'n'
}
// Word translator code using a new static\\
public static String solve (String word)
{
String temp = word.toLowerCase();
char[] vowels = {'a', 'e', 'i', 'o', 'u'}; // Stores vowels in an array
char first = temp.charAt(0); // Defines first character for later use
for (int i = 0; i < vowels.length; i++) // Looks for first vowel to replace it
{
if (first == vowels[i])
{
return word + "way"; // Replaces checked vowel
}
}
word = word.substring(1); // Returns the string to the end of the word
word += first + "ay";
return word; // Returns the translated word to the program above
}
}
Well, you are asking for the input here:
playGame = stdIn.next();
That simply has to go into your loop then:
playOn = true;
while(playOn) {
playGame = stdIn.next();
if ( y ) { ... play
} else {
if ( n ) { ... dont play, set playOn = false
} else {
... ask again
}
}
The above is just meant as inspiration, and to point: what really matters here is that you get your if/else chain, and the corresponding "blocks" right. You need another if/else completely within the first "else" block!
Since the part of your code that you want to be repeated is only the initial question, that is all that should be in the loop:
boolean askAgain = true;
while(askAgain) {
// print your prompt;
playGame = stdIn.next();
if (playGame.equals("y") || playGame.equals("n")) {
askAgain = false;
}
}
// Now do your if/elseif for which letter was retrieved.
It's good practice to only loop over parts of your code that may actually be repeated.
You'll want to have your playGame = stdIn.next(); line and prompt to run at the start of the while loop instead of just before it. Then you can check if it is y, n or something else just after that.
What can I do to modify this, is there any java function for that?
What needs to be done so that it only accepts characters and returns an error message for other data types?
import java.util.*;
public class problem5
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
System.out.print("Enter a letter from the alphabet: ");
char letter = in.next(".").charAt(0);
char vowels[] = {'A','E','I','O','U','a','e','i','o','u'};
int vowelcount = 0;
for (int i = 0; i < 10; i++)
{
if (vowels[i] == letter)
{
vowelcount++;
}
}
if (vowelcount > 0)
{
System.out.println("You entered a vowel.");
}
else
{
System.out.println("You entered a consonant.");
}
}
}
I need to reject input that has more than 1 char – Nico Dela Cruz
You just need to check the length of your input
String input = in.next(".");
if(input.length == 1){
char letter = input.charAt(0);
...
}
Add an else if you want to add an error message of some sort.
To check the input to only accept letter, you have Character.isLetter(char) to check every "letter" in UNICODE for you.
If you want to only accept a range of a-z and/or A-Z, you can do it yourself with an if condition or using regex.
Wrap your loop in a statement such as:
if (Character.isLetter(letter)){
and put and else clause at the end for your error
Edit:
OP has changed their question slightly, so you can either:
-Accept only the first character entered:
char letter = in.next().trim().charAt(0);
-Or as AxelH said above, only proceed if user enters one char:
if(input.length == 1){
char letter = input.charAt(0);
This is probably a really simple mistake, but I'm a beginner with Java (and programming in general) and I was curious why the break statement won't work in my program.
public class ValidateStudentNumber
{
public static void main(String[] args)
{
Scanner kb = new Scanner(System.in);
do{
System.out.println("Enter a number: ");
String number = kb.next();
boolean valid = true;
for (int i = 0; i < number.length(); i++){
char c = number.charAt(i);
if(! Character.isDigit(c)) {
valid = false;
break;
}
if ( number.length() != 7) {
valid = false;
}
}
if (valid){
System.out.println("Valid");
}
else{
System.out.println("Invalid");
}
}
while (kb.hasNext());
System.out.println ("Program ending due to end-of-file");
}
}
What I want to accomplish with this code is that as soon as a letter is typed, the breaks out of the for statement and displays "Invalid", yet when I run the program and type something that is a non-digit, it doesn't leave the for loop and allows me to continue typing as usual.
Thank you for your time.
Break statement is working fine. Because it breaks the execution of for loop not for do-while loop. If you want to break do-while loop add break statement in not valid case else block.
public class A
{
public static void main(String[] args)
{
Scanner kb = new Scanner(System.in);
do{
System.out.println("Enter a number: ");
String number = kb.next();
boolean valid = true;
for (int i = 0; i < number.length(); i++){
char c = number.charAt(i);
if(! Character.isDigit(c)) {
valid = false;
break;
}
if ( number.length() != 7) {
valid = false;
}
}
if (valid){
System.out.println("Valid");
}
else{
System.out.println("Invalid");
break;
}
}
while (kb.hasNext());
System.out.println ("Program ending due to end-of-file");
}
}
What I want to accomplish with this code is that as soon as a letter is typed, the breaks out of the for statement and displays "Invalid"
If I understand your question correctly, you want your loop to break when you literally hit a non-digit key on the keyboard while entering a number.
From the Scanner java docs...
A scanning operation may block waiting for input.
What is probably happening is the console is blocked waiting for a carriage return (i.e. for you to hit Enter) to then process your input. So your program is not running for every key press, but is waiting for an entire line to be entered.
This is most apparent when you remove your do-while loop. When that is removed, you can see you can enter many characters until you hit Enter where your program determines if the string entered is valid then the program ends.
In summary, program not run for every key press, just when you hit "Enter".
Edit -
Here's a question (and possible solution to your problem) trying to figure out how to read one character at a time. Looks like you need to put your console in "raw" mode.
How to read a single char from the console in Java (as the user types it)?
You seem like you wanted to break out of the do/while not just the for loop. This can be accomplished by labeling your loops. So you could rewrite your code like:
class ValidateStudentNumber
{
public static void main(String[] args)
{
Scanner kb = new Scanner(System.in);
outer:do{
System.out.println("Enter a number: ");
String number = kb.next();
for (int i = 0; i < number.length(); i++){
char c = number.charAt(i);
if(! Character.isDigit(c) || number.length() != 7) {
System.out.println("Invalid");
break outer;
}
}//end of for loop
}while (kb.hasNext());
System.out.println ("Program ending due to end-of-file");
}
}
break will make you exit the loop containing the break statement i.e. in your code it will break you out of the for-loop. Then it keeps on waiting for input from scanner. As soon as you type something again, condition is true and then the loops re-runs.
New to programming, and I'm trying to create a "Guess the letter" game. The idea is that the first person presses a key, then the second person presses a key to see if she has guessed it right.
Here is my code:
package bookExamples;
public class GuessTheLetterGame {
public static void main(String[] args) throws java.io.IOException{
char answer;
System.out.print("press a key and press ENTER:");
answer= (char) System.in.read();
char guess;
System.out.print("Have a guess and press ENTER: ");
guess = (char) System.in.read();
if (guess == answer)
System.out.println("**Right**");
}
}
It runs okay until the line "Have a guess and press ENTER:", then I tried to press a key again, the code has no reaction.
Thank you in advance :)
By casting a System.in.read() to char you are casting a byte from system to UTF-16. Therefore char c = (char) System.in.read(); will only work for very limited input.
I would recommend using Scanner to read in an entire line.
String answer = "A";
Scanner scanner = new Scanner(System.in);
String guess = "";
while(! answer.equalsIgnoreCase(guess))
{
guess = scanner.nextLine();
}
System.out.println("CONGRATULATIONS YOU WON!");
Here's another one that matches original code intent but provides a Scanner and while loop until there is a match
import java.util.Scanner;
public class GuessTheLetterGame {
public static void main(String[] args) throws java.io.IOException{
Scanner keyboard = new Scanner(System.in);
char answer;
char guess;
boolean right = false;
while(!right){
System.out.print("press a key and press ENTER:");
answer= (char) keyboard.next().charAt(0);
System.out.print("Have a guess and press ENTER: ");
guess= (char) keyboard.next().charAt(0);
if (guess == answer){
System.out.println("**Right**");
right = true;
}
}
}
}
I am also learning Java and wanted a way to make this program work using the commands I know (Scanner is more advanced).
As mentioned by Pshemo and Andreas, the System.in buffer has a 'linefeed' character (ASCII 10) still in it (assuming only a single character for 'answer' was entered).
By 'reading' that character the buffer is emptied and the next time System.in.read() is used it will take an entry as expected. I added 'linFed' to clear it.
package BookExamples;
public class GuessTheLetterGame {
public static void main(String[] args) throws java.io.IOException{
char answer;
System.out.print("press a key and press ENTER:");
answer= (char) System.in.read();
char linFed;
linFed= (char) System.in.read();
char guess;
System.out.print("Have a guess and press ENTER: ");
guess = (char) System.in.read();
if (guess == answer)
System.out.println("**Right**");
}}
In your code there is no loop to keep guessing. It's just a one shot deal. To keep guessing, you need to repeat a part of your code.
package bookExamples;
public class GuessTheLetterGame {
public static void main(String[] args) throws java.io.IOException{
char answer;
answer= 'A';
char guess = '\0';
Scanner scanner = new Scanner(System.in);
while(answer != guess) {
System.out.print("Have a guess and press ENTER: ");
guess = scanner.next().charAt(0);
System.out.println(guess);
}
System.out.println("**Right**");
}
If you keep guessing until the answer is right, you no longer need the if statement. The only thing left to keep the formatting correct, is to show the user their guess and start a new line.
NOTE: changed the code to use a scanner, and scanner.next() to get one character at a time.
I have tried to find guidance on this, but I keep getting solutions on an entire string, or a single character. I am in my 4th week of Java, and have hit a roadblock.
I have to ask a user to input three letters ("Enter three letters: abc"). Depending on which case they type, I have to write a program that swaps upper with lower and visa versa. For example, if the user types "aBc", my output will be "AbC".
This is what I have so far. If my code is horrible, I'm sorry. I'm learning as I go.
import java.util.Scanner;
public class LowerUpper {
public static void main(String[]args) {
Scanner input = new Scanner(System.in);
System.out.print("Please enter three letters: ");
String letters = input.nextLine();
for (int i = 0; i < letters.length(); i++) {
char letter1 = letters.charAt(0);
char letter2 = letters.charAt(1);
char letter3 = letters.charAt(2);
if (Character.isUpperCase(letters.charAt(0)) == true)
System.out.println(Character.toLowerCase(letter1));
else {
System.out.println(Character.toUpperCase(letter1));
}
if (Character.isUpperCase(letters.charAt(1)) == true)
System.out.println(Character.toLowerCase(letter2));
else {
System.out.println(Character.toUpperCase(letter2));
}
if (Character.isUpperCase(letters.charAt(2)) == true)
System.out.println(Character.toLowerCase(letter3));
else {
System.out.println(Character.toUpperCase(letter3));
}
}
}
}
When I typed "abc" for the input, the output was:
A
B
C
A
B
C
A
B
C
The format of the output is supposed to be "Result: ABC". I can work on that later. I'm just trying to figure out how to get this to execute correctly. My hunch is that I'm definitely going wrong on my if/else statements. I do not know how to print the changed chars all in a row (abc, AbC, ABC, etc). I thought I did it correctly at the beginning with the indexing of the string (0,1,2).
By the way, it's not showing my output correctly this forum. It is supposed to be one letter per line, not "ABCABCABC", if I made sense with that.
The reasoning for this is because it's inside of a for loop, which is essentially worthless, because you are never using the integer 'i'. If you remove the for loop, it should only execute once, thus for outputting "ABC", instead of "A B C A B C A B C". To print the chars in a row, you can simply append each character to a string, and then output that.
The biggest issue I see is that you've got a loop going over the length of the string but you're not using the loop index i to reference the individual characters. In short, you're trying too hard and overlooking the obvious.
Wouldn't this do the trick?
for (int i = 0; i < letters.length(); i++) {
char letter1 = letters.charAt(0);
if (Character.isUpperCase(letter1)) {
System.out.println(Character.toLowerCase(letter1));
} else {
System.out.println(Character.toUpperCase(letter1));
}
}
The reason why you get a redundant printing 'coz you loop the three variables which already contain all characters.
To solve your problem. just remove the for loop. 'coz you already
store each character to the three variables.
You code will look like this now:
import java.util.Scanner;
public class LowerUpper {
public static void main(String[]args) {
Scanner input = new Scanner(System.in);
System.out.print("Please enter three letters: ");
String letters = input.nextLine();
char letter1 = letters.charAt(0);
char letter2 = letters.charAt(1);
char letter3 = letters.charAt(2);
if (Character.isUpperCase(letters.charAt(0)) == true)
System.out.println(Character.toLowerCase(letter1));
else {
System.out.println(Character.toUpperCase(letter1));
}
if (Character.isUpperCase(letters.charAt(1)) == true)
System.out.println(Character.toLowerCase(letter2));
else {
System.out.println(Character.toUpperCase(letter2));
}
if (Character.isUpperCase(letters.charAt(2)) == true)
System.out.println(Character.toLowerCase(letter3));
else {
System.out.println(Character.toUpperCase(letter3));
}
}
}
Ok, here is my new code. It compiled with no errors and the output was just as it was supposed to be:
import java.util.Scanner;
public class LowerUpper {
public static void main(String[]args) {
Scanner input = new Scanner(System.in);
System.out.print("Please enter three letters: ");
String letters = input.nextLine();
char letter1 = letters.charAt(0);
char letter2 = letters.charAt(1);
char letter3 = letters.charAt(2);
if (Character.isUpperCase(letters.charAt(0)) == true)
System.out.print("Result: " + Character.toLowerCase(letter1));
else {
System.out.print("Result: " + Character.toUpperCase(letter1));
}
if (Character.isUpperCase(letters.charAt(1)) == true)
System.out.print(Character.toLowerCase(letter2));
else {
System.out.print(Character.toUpperCase(letter2));
}
if (Character.isUpperCase(letters.charAt(2)) == true)
System.out.print(Character.toLowerCase(letter3));
else {
System.out.print(Character.toUpperCase(letter3));
}
}
}
The problem is that you have a loop then do each letter individually. So get rid of the loop. It would look better if you re-wrote it with a loop but only had one if/else statement inside the loop based on i not 0,1&2.
Replace your for loop with:
System.out.println(letters.toUpperCase());