我正在学习JAVA并键入以下DO ... WHILE示例。如果输入'q',程序将退出。它运行,但为什么我得到三行“请一键,然后按ENTER:”?
class DWDemo {
public static void main (String args[])
throws java.io.IOException {
char ch;
do {
System.out.println("Please a key followed by ENTER:");
ch = (char) System.in.read();
} while (ch != 'q');
}
}
答案 0 :(得分:10)
因为当您键入a
并点击Enter
时,in.read()
方法会返回三个字符 - 'a'
,回车符\r
和换行符('\n'
)。 (请注意,组合\r\n
在Windows下被视为换行符。)
如果您在Linux或OSX下运行它,程序将有明显不同的行为,因为换行符特定于您运行程序的操作系统。在Linux下,它将是\n
,在OS X-9下,它将是\r
,例如。
作为解决方法,您可以阅读整行(使用Scanner
)并修剪它,这将省略换行符(忽略操作系统类型):
public static void main (String args[]) throws java.io.IOException {
String line;
Scanner sc = new Scanner(System.in);
do {
System.out.println("Please a key followed by ENTER:");
line = sc.readLine().trim();
} while (!"q".equals(line));
}
答案 1 :(得分:5)
我假设读取的内容包含您的ENTER按键。由于您使用的是Windows,因此包括CRFL行结尾。
因此,每次输入char时,实际输入3个字符。第一次输入:
尝试通过BufferedReader读取整行并在其上运行空白修剪,或者仅评估其第一个字符。
答案 2 :(得分:3)
在Windows系统的命令行上键入输入时,所有行都以包含字符\r\n
的换行符结束。因此,当您第一次键入a
时,实际上是在键入a\r\n
。
运行代码System.in.read()
时,它只读取已输入缓冲区的第一个字符,在本例中为a
。然后循环运行,打印出你的提示并尝试读取缓冲区上的下一个字符。在这种情况下,\r\n
仍在缓冲区上,因此它会读入\r
。再次循环,它读入\n
。最后,由于缓冲区为空,它会第三次打印提示,它等待您的输入。
为了避免这种情况,我建议使用不同的方法从命令行而不是System.In
读入。也许Scanner类更合适。
答案 3 :(得分:1)
您必须注意的一件事是SELECT m.Name, COUNT(COALESCE(c.regNo, 0)) as Count
FROM
(
VALUES ('Janurary'), ('February'), ('March'),
('April'), ('May'), ('June'),
('July'), ('August'), ('September'),
('October'), ('November'), ('December')
) AS m(Name)
LEFT JOIN Company c ON DATETNAME(MONTH, c.postTime) = m.Name
AND DATENAME(YEAR, c.postTime) = 2015
GROUP BY m.Name;
只接受1个字节的输入。请参阅文档here。因此,当您输入字符System.in.read()
时,通过输入其他 ENTER 键,字符为a
和\r
,这已经是一个字节由\n
两次,这会触发额外的循环迭代和打印逻辑。
答案 4 :(得分:0)
正如@kasoban所说,他们是CR,LF。它重复3次,但会根据操作系统改变。所以我建议你使用扫描仪。你可以在下面找到样本
public class DW {
public static void main (String args[]) throws java.io.IOException {
String s;
Scanner scanner = new Scanner(System.in);
do {
System.out.println("Please a key followed by ENTER:");
s = scanner.nextLine();
} while (!"q".equals(s));
}
}