Java System.in.read()行为我可以';无法解释

Java System.in.read()行为我可以';无法解释,java,string,output,Java,String,Output,但结果是: F i r s t... 我不确定为什么每次按enter键(\n)时,一行中会显示两个字符 我正在运行windows 8,并使用命令提示符使用javac运行文件。这将解决您遇到的问题,但我无法解释为什么System.in.read()会出现这种奇怪的行为 类E92StringDemo{ 公共静态扫描仪阅读器=新扫描仪(System.in); 公共静态void main(字符串[]args){ String strObj1=“第一个字符串”; 对于(int i=0;i

但结果是:

F
i
r
s
t...
我不确定为什么每次按
enter
键(\n)时,一行中会显示两个字符


我正在运行windows 8,并使用命令提示符使用
javac
运行文件。这将解决您遇到的问题,但我无法解释为什么System.in.read()会出现这种奇怪的行为

类E92StringDemo{
公共静态扫描仪阅读器=新扫描仪(System.in);
公共静态void main(字符串[]args){
String strObj1=“第一个字符串”;
对于(int i=0;i
这将解决您的问题,但我无法解释为什么System.in.read()会出现这种奇怪的行为

类E92StringDemo{
公共静态扫描仪阅读器=新扫描仪(System.in);
公共静态void main(字符串[]args){
String strObj1=“第一个字符串”;
对于(int i=0;i
使用

而不是

  new Scanner(System.in).nextLine();
您还可以使用
System.in.read
获得此结果,因为它返回
int
除了字节的所有可能值之外,还需要能够返回额外的值以指示流的结束。因此,它必须返回一个类型,该类型可以表示比字节更多的值

然而,根据其文件

 System.in.read();
使用

而不是

  new Scanner(System.in).nextLine();
您还可以使用
System.in.read
获得此结果,因为它返回
int
除了字节的所有可能值之外,还需要能够返回额外的值以指示流的结束。因此,它必须返回一个类型,该类型可以表示比字节更多的值

然而,根据其文件

 System.in.read();
问题
System.in.read()

但在控制台中,当您按ENTER键时,会发生两件事:

  • 控制台光标移动到下一行
  • 依赖操作系统的行分隔符*放在标准输入中,Windows的标准输入是
    \r\n

    • 回车符
      \r
      -放置在
    • 换行符
      \n
      -放置在
所以,正如您看到的,若要在下一次迭代中暂停循环,则需要在离开当前迭代之前清空输入流中的数据。但是
System.in.read()
一次只读取一个字符,在您的情况下,
\r
\n
留给下一次迭代(因此没有暂停)

所以,在暂停再次可用之前,您需要在一次迭代中阅读两次

解决方案 如果您想以独立于操作系统的方式解决此问题,请使用
BufferedReader#readLine()
Scanner#nextLine
如下:

/**
 * Reads the next byte of data from the input stream. The value byte is
 * returned as an <code>int</code> in the range <code>0</code> to
 * <code>255</code>. If no byte is available because the end of the stream
 * has been reached, the value <code>-1</code> is returned. This method
 * blocks until input data is available, the end of the stream is detected,
 * or an exception is thrown.
 *
 * <p> A subclass must provide an implementation of this method.
 *
 * @return     the next byte of data, or <code>-1</code> if the end of the
 *             stream is reached.
 * @exception  IOException  if an I/O error occurs.
 */

public abstract int read() throws IOException;
String strObj1=“第一个字符串”;
try(Scanner sc=new Scanner(System.in)){//将自动关闭资源
对于(int i=0;i
这些方法还解决了在按enter键之前可能放置额外字符的问题,因为它们中的每一个字符都将被放置在标准输入流中,这将需要额外的
.read()
调用


*以及按enter键之前提供的其他潜在字符问题
System.in.read()

但在控制台中,当您按ENTER键时,会发生两件事:

  • 控制台光标移动到下一行
  • 依赖操作系统的行分隔符*放在标准输入中,Windows的标准输入是
    \r\n

    • 回车符
      \r
      -放置在
    • 换行符
      \n
      -放置在
所以,正如您看到的,若要在下一次迭代中暂停循环,则需要在离开当前迭代之前清空输入流中的数据。但是
System.in.read()
一次只读取一个字符,在您的情况下,
\r
\n
留给下一次迭代(因此没有暂停)

所以,在暂停再次可用之前,您需要在一次迭代中阅读两次

解决方案 如果您想以独立于操作系统的方式解决此问题,请使用
BufferedReader#readLine()
Scanner#nextLine
如下:

/**
 * Reads the next byte of data from the input stream. The value byte is
 * returned as an <code>int</code> in the range <code>0</code> to
 * <code>255</code>. If no byte is available because the end of the stream
 * has been reached, the value <code>-1</code> is returned. This method
 * blocks until input data is available, the end of the stream is detected,
 * or an exception is thrown.
 *
 * <p> A subclass must provide an implementation of this method.
 *
 * @return     the next byte of data, or <code>-1</code> if the end of the
 *             stream is reached.
 * @exception  IOException  if an I/O error occurs.
 */

public abstract int read() throws IOException;
String strObj1=“第一个字符串”;
try(Scanner sc=new Scanner(System.in)){//将自动关闭资源
对于(int i=0;i
这些方法还解决了在按enter键之前可能放置额外字符的问题,因为它们中的每一个字符都将被放置在标准输入流中,这将需要额外的
.read()
调用



*在Windows上按enter键之前提供的其他潜在字符将生成2个字符(CRLF),而read()只使用其中1个。 您必须使用2个字符才能获得所需的行为。只需添加另一个
System.in.read()
,您就会看到。 以下说明按ENTER键时字符的生成和使用。13代表CR,10代表LF。

F
13i10r
13s10t
13 10秒
13t10r
13i10n
13g10

Windows上的ENTER生成2个字符(CRLF),而read()只使用其中1个字符。 您必须使用2个字符f
String strObj1 = "First String";
try(Scanner sc = new Scanner(System.in)){//will automatically close resource
    for (int i = 0; i < strObj1.length(); i++) {
        System.out.print(strObj1.charAt(i));
        sc.nextLine();
    }
}