Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/371.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么在循环中的System.in.read()之后调用我的方法3次_Java_Println_System.out - Fatal编程技术网

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

Java 为什么在循环中的System.in.read()之后调用我的方法3次,java,println,system.out,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'); } 为

我已经开始学习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
会打印三次“询问字母”。在给出任何答案之前,字符串只打印一次


提前感谢

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

q\r\n
您可以在此处找到更多详细信息:

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

    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键生成的回车和换行符

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

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

BufferedReader reader = new BufferedReader( InputStreamReader( System.in ) );
Scanner scanner = new Scanner( System.in );
然后您可以使用:

String userInput = reader.readLine();
String userInput = scanner.nextLine();
要使用
扫描仪
,请执行以下操作:

BufferedReader reader = new BufferedReader( InputStreamReader( System.in ) );
Scanner scanner = new Scanner( System.in );
然后您可以使用:

String userInput = reader.readLine();
String userInput = scanner.nextLine();

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

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

下次读命令出现时,它首先检查缓冲区,然后再等待键盘输入。在按enter键之前,请尝试输入多个字母-无论输入的字符数为+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键输入的字符),在再次调用该方法时为您留下一个新的缓冲区。

通过执行
System.in.read().substring(0,1)修复它
这只取第一个字符,等待ascii值?@user2693587数据的下一个字节,或-1表示EOF。读这本书。