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

时间:2015-04-06 10:55:12

标签: java println system.out

我已经开始学习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在给出错误的答案后打印“将该字母串起来”三次。在给出任何答案之前,字符串只打印一次。

提前致谢

3 个答案:

答案 0 :(得分:8)

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

q\r\n

您可以在此处找到更多详细信息: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');

答案 1 :(得分:2)

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

您正在这样做,您将输入视为字节流。然后,正如@Sergey Grinev所说,你得到三个字符 - 你输入的实际字符,以及按 Enter 产生的回车和换行符。

如果您希望将输入视为字符而非字节,则应创建BufferedReaderScanner支持{ {1}}。然后你可以阅读整行,它会为你处理回车符和换行符。

要使用System.in,请执行以下操作:

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进行比较,使用==。或者确保其长度大于1并使用equals()获取第一个字符。

答案 2 :(得分: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');

这样'ignore'将在缓冲区中循环,直到它到达缓冲区中的换行符(最后一个通过在Windows中按Enter键进入),当再次调用该方法时,为你留下一个新的缓冲区。