You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

System.in.read()输入单个字符返回3次?Java循环异常问题咨询

问题:输入单个字符后for循环多次执行的原因

我正在学习《Java: 从入门到精通》(原书名Java: A Beginner's Guide)一书,书中讲解for循环时给出了这段包含用户输入的代码:

class ForTest {   
  public static void main(String[] args)   
    throws java.io.IOException { 

    int i; 

    System.out.println("Press S to stop."); 

    for(i = 0; (char) System.in.read() != 'S'; i++) 
      System.out.println("Pass #" + i); 
  }   
}

执行这段代码后,输出和预期不符:输入单个字符并按下回车,程序会打印三次Pass #而非一次。以下是输出示例:

a
Pass #0
Pass #1
Pass #2
w
Pass #3
Pass #4
Pass #5
1
Pass #6
Pass #7
Pass #8
2
Pass #9
Pass #10
Pass #11

原因解析

这是因为你按下回车时,输入流里不止有你输入的目标字符,还有换行相关的控制字符:Windows系统中,回车会生成\r(回车符)和\n(换行符)两个字符;Linux/macOS中则是\n。而System.in.read()是逐个字节读取输入的,每次调用会读取一个字符,这些控制字符都会被当作循环判断的输入。

拿输入a并回车的场景举例:

  • 输入流里实际包含三个字符:a、\r、\n
  • 循环条件每次都会调用System.in.read()读取一个字符:
    1. 第一次读取a,不等于S,执行循环,打印Pass #0
    2. 第二次读取\r,不等于S,执行循环,打印Pass #1
    3. 第三次读取\n,不等于S,执行循环,打印Pass #2
  • 直到输入流里的字符全部读完,程序才会等待下一次输入,所以每次输入字符加回车会触发三次循环。

解决方法

如果想让输入一个字符只触发一次循环,可以改用Scanner类来读取完整的输入行,避免逐个字节读取控制字符的问题:

import java.util.Scanner;

class ForTest {   
  public static void main(String[] args) { 
    Scanner scanner = new Scanner(System.in);
    int i; 

    System.out.println("Press S to stop."); 

    for(i = 0; !scanner.nextLine().trim().equals("S"); i++) 
      System.out.println("Pass #" + i); 
    scanner.close();
  }   
}

这里用scanner.nextLine()读取整行输入,trim()可以去掉输入前后的空白字符(包括回车换行),只有当输入的内容是S时才会终止循环。


内容的提问来源于stack exchange,提问作者Guilherme

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 00:05:15