Java 输入缓冲区和 do-while 循环行为(为什么它检查第一个字符 3 次?)

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

我一直在学习 Java Oracle 的“Java 初学者指南”,但在理解书中关于输入缓冲区和 do-while 循环的示例程序时遇到了困难。

这个例子是关于一个猜数程序的。它旨在忽略您可能输入的任何额外字符。因此,如果您输入 ABC 然后按回车,它只会检查 A。

我的问题更多是关于输入缓冲区,如果我注释掉处理忽略的第二个 do-while 循环然后 运行 程序,它会检查单个字符 3 次。因此,如果我输入一个“A”,然后按回车键,它似乎会检查 3 次,然后我会得到 3 次“...抱歉,你太低了”输出提示。

如果我输入“AZ”然后按回车,它似乎检查了 4 次,它检查了 A,然后 Z,然后再检查 A 2 次。


问题:

  1. 为什么它似乎总是检查第一个字符 3 次?
  2. 回车键是否将\n赋给忽略变量?
    当第二个 do-while 循环没有被注释掉时,如果输入 ABC 然后按回车,这是正确的顺序吗?
    A – 分配给 ch
    B-分配忽略
    C-分配忽略
    Enter key (\n) – 分配给 ignore,循环退出,因为分配了 ignore \n

如果回车键实际上指定了\n忽略,我有点困惑?还是只是等到没有更多的字符可以分配给忽略?这本书说按回车会导致换行。因此,do-while 循环在以下情况下终止:(忽略 != '\n')。

感谢您的帮助!

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);
        }
}

问题 1:

(正如我在评论中所写,如果我只输入一个字符,我不会得到 3 行,我得到 2,这是正确的行为)

您认为第一个字符被多次检查的假设是错误的。为了简单调试,打印要测试的字符:

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

现在,当您输入 abc[enter] 时,您会看到每个字符都被单独处理,并且每个字符都会导致相同的消息。还测试了换行符。

问题 2:

你完全正确。

但有一件重要的事情:第二个 do-while 结构的全部要点是为您的下一次猜测清除输入流! 这就是上面的评论至少试图指出的:discard any other characters in the input buffer。检查换行符只是为了让您知道可以退出循环,因为一次猜测仅限于一行!实际上你根本不需要那个忽略变量。字符通过读取从流中移除。所以这是关于通过调用 System.in.read() 读取本身 - 您不必将结果分配给任何东西。

您可以将第二个 do-while 循环替换为 do {} while(System.in.read() != '\n');.