Java System.in.read()行为解析:处理用户输入中的回车符

admin 百科 11

Java System.in.read()行为解析:处理用户输入中的回车符

system.in.read()在处理用户输入时,除了读取用户键入的字符外,还会读取回车符和换行符,导致循环或条件判断意外执行多次。本文将深入分析这一现象的成因,并提供一种健壮的方法来正确处理低级别字符输入,确保程序按预期逻辑运行。

引言:System.in.read()的意外行为

在Java中,System.in.read()是一个低级别的输入方法,用于从标准输入流中读取单个字节的数据。它返回读取到的字节的整数表示(0-255),如果到达流的末尾则返回-1。当我们需要在循环中根据用户输入的单个字符来控制程序流程时,可能会遇到一些意想不到的行为。

考虑以下代码示例,它尝试在用户输入非'S'字符时持续循环:

import java.io.IOException;

public 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);
  }
}

登录后复制

当运行这段代码并输入一个字符(例如'a')后按下回车键,预期是循环体执行一次,然后等待下一次输入。然而,实际输出却显示循环体执行了三次:

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

登录后复制

这种现象表明,每次用户输入一个字符并按下回车键,System.in.read()似乎被调用了三次,导致循环体意外地执行了多次。

立即学习“Java免费学习笔记(深入)”;

深入解析:回车与换行符的影响

这种“三次输出”的根源在于操作系统和Java对键盘输入以及行结束符的处理方式。当用户在命令行界面输入一个字符(例如'a')并按下Enter键时,System.in实际上接收到的不仅仅是字符'a',还包括了行结束符。

在大多数操作系统中,按下Enter键会产生以下一个或两个控制字符:

  • 回车符 (Carriage Return, \r):ASCII值为13。
  • 换行符 (Line Feed, \n):ASCII值为10。

具体来说:

  • Windows系统:按下Enter键通常会生成一对字符:\r\n。
  • Unix/Linux/macOS系统:按下Enter键通常只生成一个字符:\n。

由于System.in.read()每次调用都会从输入缓冲区中读取并返回一个字节,因此,当用户输入'a'并按下Enter(在Windows上产生\r\n)时,输入缓冲区中会依次包含'a'、\r和\n这三个字符。

回到我们的for循环条件:(char) System.in.read() != 'S'。

Java System.in.read()行为解析:处理用户输入中的回车符-第2张图片-佛山资讯网

  1. 第一次循环条件判断:System.in.read()读取到字符'a'。条件('a' != 'S')为真,循环体System.out.println("Pass #" + i);执行。
  2. 第二次循环条件判断:System.in.read()读取到回车符\r。条件('\r' != 'S')为真,循环体再次执行。
  3. 第三次循环条件判断:System.in.read()读取到换行符\n。条件('\n' != 'S')为真,循环体第三次执行。
  4. 此时,输入缓冲区已被清空,程序会暂停,等待用户输入新的字符。

这就是为什么每次输入一个字符并按Enter键,循环体会执行三次的原因。

标签: linux java windows 操作系统 字节 工具 mac ai unix macos win windows系

发布评论 0条评论)

还木有评论哦,快来抢沙发吧~