I have started to learn Java, wrote couple of very easy things, but there is a thing that I don't understand:
public static void main(String[] args) throws java.io.IOException
{
char ch;
do
{
System.out.println("Quess the letter");
ch = (char) System.in.read();
}
while (ch != 'q');
}
Why does the System.out.println
prints "Quess the letter" three times after giving a wrong answer. Before giving any answer string is printed only once.
Thanks in advance
Because when you print char and press Enter you produce 3 symbols (on Windows): character, carriage return and line feed:
You can find more details here: http://en.wikipedia.org/wiki/Newline
For your task you may want to use higher level API, e.g.
Scanner
:Using
System.in
directly is probably the wrong thing to do. You'll see that if your character is changed fromq
to something in Russian, Arabic or Chinese. Reading just one byte is never going to match it. You are just lucky that the bytes read from console in UTF-8 match the character codes for the plain English characters.The way you are doing it, you are looking at the input as a stream of bytes. And then, as @Sergey Grinev said, you get three characters - the actual character you entered, and the carriage return and line feed that were produce by pressing Enter.
If you want to treat your input as characters, rather than bytes, you should create a
BufferedReader
or aScanner
backed bySystem.in
. Then you can read a whole line, and it will dispose of the carriage return and linefeed characters for you.To use a
BufferedReader
you do something like:And then you can use:
To use a
Scanner
, you do something like:And then you can use:
In both cases, the result is a
String
, not achar
, so you should be careful - don't compare it using==
but usingequals()
. Or make sure its length is greater than 1 and take its first character usingcharAt(0)
.As has been mentioned, the initial read command takes in 3 characters and holds them in the buffer.
The next time a read command comes around, it first checks the buffer before waiting for a keyboard input. Try entering more than one letter before hitting enter- your method should get called however many characters you entered + 2.
For an even simpler fix:
this way 'ignore' will cycle through the buffer until it hits the newline character in the buffer (the last one entered via pressing enter in Windows) leaving you with an fresh buffer when the method is called again.