为什么我的方法在循环中System.in.read()之后被调用了3次



我已经开始学习Java,写了一些非常简单的东西,但有一件事我不理解:

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

为什么System.out.println在给出错误答案后会打印三次"Quess the letter"。在给出任何答案之前,字符串只打印一次。

提前感谢

因为当您打印字符并按Enter时,您会产生3个符号(在Windows上):字符、回车和换行:

qrn

您可以在此处找到更多详细信息:http://en.wikipedia.org/wiki/Newline

对于您的任务,您可能希望使用更高级别的API,例如Scanner:

    Scanner scanner = new Scanner(System.in);
    do {
        System.out.println("Guess the letter");
        ch = scanner.nextLine().charAt(0);
    } while (ch != 'q');

直接使用System.in可能是错误的做法。如果您的字符从q更改为俄语、阿拉伯语或中文,您会看到这种情况。只读取一个字节是永远不会匹配的。你很幸运,从控制台读取的UTF-8字节与普通英语字符的字符代码匹配。

按照您的方式,您将输入视为字节流。然后,正如@Sergey Grinev所说,你会得到三个字符——你输入的实际字符,以及通过按下Enter产生的回车和换行。

如果要将输入视为字符,而不是字节的输入,则应创建一个由System.in支持的BufferedReaderScanner。然后您可以读取整行,它将为您处理回车和换行字符。

要使用BufferedReader,您可以执行以下操作:

BufferedReader reader = new BufferedReader( InputStreamReader( System.in ) );

然后你可以使用:

String userInput = reader.readLine();

要使用Scanner,您可以执行以下操作:

Scanner scanner = new Scanner( System.in );

然后你可以使用:

String userInput = scanner.nextLine();

在这两种情况下,结果都是String,而不是char,所以您应该小心——不要使用==而是使用equals()进行比较。或者确保其长度大于1,并使用charAt(0)获取其第一个字符。

如前所述,初始读取命令接收3个字符并将它们保存在缓冲区中。

下次出现读取命令时,它会在等待键盘输入之前先检查缓冲区。在点击回车键之前,请尝试输入多个字母-无论您输入了多少字符+2,都应该调用您的方法。

对于更简单的修复:

//add char 'ignore' variable to the char declaration
char ch ignore;
//add this do while loop after the "ch = (char) System.in.read();" line
do{
    ignore = (char) System.in.read();
} while (ignore != 'n');

通过这种方式,"忽略"将在缓冲区中循环,直到它碰到缓冲区中的换行符(在Windows中通过按enter键输入的最后一个字符),在再次调用该方法时留下一个新的缓冲区。

最新更新