System.in.read()行为我无法解释

时间:2017-04-06 12:12:22

标签: java string output

class E92StringDemo {

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

      String strObj1 = "First String";

      for(int i=0;i<strObj1.length();i++) {

        System.out.print(strObj1.charAt(i));
        System.in.read(); //just to pause the execution till i press enter key

      }
   }
}

我希望输出如下:

F
i
r
s
t...

但输出结果如下:

F
ir
st
S
tr
in
g

我不确定每次按enter键(\ n)后,如何在一行中显示2个字符?

我正在运行 Windows 8 ,并使用命令提示符使用javac运行该文件。

4 个答案:

答案 0 :(得分:3)

问题

如果标准输入流中没有要读取的数据(由System.in.read()表示),则

System.in仅保留应用程序的执行。

但是在按下ENTER的控制台中,会发生两件事:

因此,当您看到是否要在每次下一次迭代中暂停循环时,您需要在离开当前迭代之前从输入流中清空数据。但System.in.read()一次仅读取一个字符,在您的情况下\r\n留给下一次迭代(因此不会暂停)。

因此,在暂停之前,您需要在一次迭代中读取两次。

解决方案

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

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

这些方法还解决了在按Enter之前放置的潜在额外字符的问题,因为它们中的每一个也将被放置在标准输入流中,这将需要额外的.read()调用。

* 以及在按Enter键之前提供的其他潜在字符

答案 1 :(得分:1)

这将解决您遇到的问题,但我无法解释为什么您使用System.in.read()获得这种奇怪的行为。

class E92StringDemo {
    public static Scanner reader = new Scanner(System.in);

    public static void main(String[] args) {

        String strObj1 = "First String";

        for(int i = 0; i < strObj1.length(); i++) {
            System.out.print(strObj1.charAt(i));
            reader.nextLine(); //just to pause the execution till i press enter key
        }
    }
}

答案 2 :(得分:1)

使用

  new Scanner(System.in).nextLine();

而不是

 System.in.read();

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

然而根据其文件。

/**
 * 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;

答案 3 :(得分:1)

Windows上的ENTER生成2个字符(CRLF),而read()仅消耗其中1个。 您必须为所需行为消耗2个字符。只需添加另一个System.in.read(),您就会看到。

以下说明按ENTER时字符的生成和消耗。 13代表CR,10代表LF。 F 13i10r 13s10t 13 10S 13t10r 13i10n 13g10