一个非常简单的 java do...while 循环
A very simple java do...while loop
我正在学习 JAVA 并输入了以下 DO...WHILE 示例。如果我键入 'q',程序将退出。它运行但为什么我得到三行 "Please a key followed by 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');
}
}
我假设读取为输入的内容包含您的 ENTER 按键。由于您在 Windows,这包括 CRFL 行结尾。
因此,每次输入字符时,实际上输入了 3 个字符。对于您的第一个输入:
- 一个
- CR
- LF
尝试通过 BufferedReader 和 运行 空白 trim 读取整行,或者只评估其第一个字符。
因为当你键入 a
并点击 Enter
时,in.read()
方法 return 的三个字符 - 'a'
,回车字符 return \r
和换行符 ('\n'
)。 (请注意组合 \r\n
在 Windows 下被视为换行符)。
如果您在 Linux 或 OSX 下 运行 您的程序将有明显不同的行为,因为换行符特定于 OS 你正在 运行 启动程序。例如在Linux下就是\n
,在OSX-9下就是\r
。
作为变通方法,您可以读取整行(通过使用 Scanner
)并 trim 它,这将省略换行符(忽略 OS类型):
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));
}
在 Windows 系统的命令行中键入输入时,所有行都以由字符 \r\n
组成的换行符结束。所以当你第一次输入 a
时,你实际上输入的是 a\r\n
。
当代码 System.in.read()
为 运行 时,它只读取已输入缓冲区的第一个字符,在本例中为 a
。然后循环 运行s,打印出您的提示并尝试读取缓冲区中的下一个字符。在这种情况下,\r\n
仍在缓冲区中,因此它读入 \r
。再次循环并读入 \n
。最后它第三次打印提示,因为缓冲区是空的,它等待你的输入。
为了避免这种情况,我建议使用不同的方法从命令行读取,而不是 System.In
。也许 Scanner class 更合适。
你必须注意的一件事是 System.in.read()
只接受 1 个字节的输入。请参阅文档 here。因此,当您输入一个字符 a
时,这已经是一个字节,通过输入一个额外的 ENTER 键,字符:\r
和 \n
,即将被 read()
捕获两次,这会触发额外的循环迭代和打印逻辑。
正如@kasoban 所说,它们是 CR 和 LF。就是重复3次,但是会根据OS变化。所以我建议你使用扫描仪。您可以在下面找到示例
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));
}
}
我正在学习 JAVA 并输入了以下 DO...WHILE 示例。如果我键入 'q',程序将退出。它运行但为什么我得到三行 "Please a key followed by 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');
}
}
我假设读取为输入的内容包含您的 ENTER 按键。由于您在 Windows,这包括 CRFL 行结尾。
因此,每次输入字符时,实际上输入了 3 个字符。对于您的第一个输入:
- 一个
- CR
- LF
尝试通过 BufferedReader 和 运行 空白 trim 读取整行,或者只评估其第一个字符。
因为当你键入 a
并点击 Enter
时,in.read()
方法 return 的三个字符 - 'a'
,回车字符 return \r
和换行符 ('\n'
)。 (请注意组合 \r\n
在 Windows 下被视为换行符)。
如果您在 Linux 或 OSX 下 运行 您的程序将有明显不同的行为,因为换行符特定于 OS 你正在 运行 启动程序。例如在Linux下就是\n
,在OSX-9下就是\r
。
作为变通方法,您可以读取整行(通过使用 Scanner
)并 trim 它,这将省略换行符(忽略 OS类型):
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));
}
在 Windows 系统的命令行中键入输入时,所有行都以由字符 \r\n
组成的换行符结束。所以当你第一次输入 a
时,你实际上输入的是 a\r\n
。
当代码 System.in.read()
为 运行 时,它只读取已输入缓冲区的第一个字符,在本例中为 a
。然后循环 运行s,打印出您的提示并尝试读取缓冲区中的下一个字符。在这种情况下,\r\n
仍在缓冲区中,因此它读入 \r
。再次循环并读入 \n
。最后它第三次打印提示,因为缓冲区是空的,它等待你的输入。
为了避免这种情况,我建议使用不同的方法从命令行读取,而不是 System.In
。也许 Scanner class 更合适。
你必须注意的一件事是 System.in.read()
只接受 1 个字节的输入。请参阅文档 here。因此,当您输入一个字符 a
时,这已经是一个字节,通过输入一个额外的 ENTER 键,字符:\r
和 \n
,即将被 read()
捕获两次,这会触发额外的循环迭代和打印逻辑。
正如@kasoban 所说,它们是 CR 和 LF。就是重复3次,但是会根据OS变化。所以我建议你使用扫描仪。您可以在下面找到示例
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));
}
}