我已经开始学习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
支持的BufferedReader
或Scanner
。然后您可以读取整行,它将为您处理回车和换行字符。
要使用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键输入的最后一个字符),在再次调用该方法时留下一个新的缓冲区。