Java input buffer and do-while loop behavior (why does it check first character 3 times?)

Jim Anderson :

I have been learning Java with Oracle’s “Java A Beginner’s Guide”, and was having trouble understanding an example program from the book about the input buffer and do-while loop.

This example is about a number guessing program. It’s designed to ignore any extra characters you might enter. So if you enter ABC then push enter it will only check A.

My question is more about the input buffer, if I comment out the 2nd do-while loop that deals with ignore then run the program, it checks that single character 3 times. So if I enter a single ‘A’ then push enter it appears to check 3 times and I get the “...Sorry, you're too low” output blurb 3 times.

If I enter ‘AZ’ then push enter it seems to check 4 times, it checks A then Z then A 2 more times.


Questions:

  1. Why does it seem to always check the first character 3 times?
  2. Does the enter key assign \n to the ignore variable?
    When the 2nd do-while loop is not commented out, is this the correct sequence if you enter ABC then push enter?
    A – assigned to ch
    B- assigned to ignore
    C- assigned to ignore
    Enter key (\n) – assigned to ignore, loop exits because ignore is assigned \n

I am a bit confused if the enter key actually assigns \n to ignore? Or is it just waiting until there are no more characters to assign to ignore? The book says pushing enter causes a newline. So that do-while loop is terminated when: (ignore != '\n').

Thanks for any help!

class Guess4{
    public static void main (String args[])
        throws java.io.IOException {

            char ch, ignore, answer = 'K';

            do {
                System.out.println("I'm thinking of a letter between A and Z.");
                System.out.println("Can you guess it: ");

                //read a character
                ch = (char) System.in.read();

                /* discard any other characters in the input buffer
                do {
                    ignore = (char) System.in.read();
                } while(ignore != '\n');
                */

                if(ch == answer) System.out.println("**Right**");
                else {
                    System.out.print("...Sorry, you're ");
                    if(ch < answer) System.out.println("too low");
                    else System.out.println("too high");
                    System.out.println("Try again!\n");
                }
            } while(answer != ch);
        }
}
Doe Johnson :

Question 1:

(As I already wrote in my comment, I did not get 3 lines if I entered just one character, I got 2, which is correct behavior)

Your assumption that the first character is checked multiple times is wrong. For simple debugging, print the character that will be tested:

// ...
System.out.println("Now checking: '" + ch + "''");
if(ch == answer) System.out.println("**Right**");
// ...

Now, when you enter abc[enter], you will see that each character is processed individually and each of them causes the same message. Also the newline is tested.

Question 2:

You're absolutely right.

There is one important thing though: The whole point of the second do-while construct is to clear the input-stream for your next guess! That's what the comment above at least tries to point out: discard any other characters in the input buffer. Checking for the newline is just so you know you can exit the loop because one guess is limited to one line! Actually you don't even need that ignore variable at all. The character is removed from the stream by reading it. So it's about the reading itself by calling System.in.read() - you don't have to assign the result to anything.

You could replace the second do-while loop with just do {} while(System.in.read() != '\n');.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=126943&siteId=1