【问题标题】:DataInputStream Confusion数据输入流混乱
【发布时间】:2018-03-25 02:04:02
【问题描述】:

这段代码运行时怎么会,如果你把“3”作为输入,它不会将“打印”写入控制台,但“33”会写入“打印”?

public static void main(String[] args) throws Exception
{
    DataInputStream input;
    int any;

    input = new DataInputStream(System.in);
    any = input.readInt();
    System.out.println("Print");
}

【问题讨论】:

    标签: java input stream


    【解决方案1】:

    当提示输入时,按键盘上的Enter 会附加一个换行符\n。出于这个原因,输入333 并按下Enter 会生成以下存储在any 中的值:858993418

    查看DataInputStream#readInt的源代码,我们看到以下内容:

    public final int readInt() throws IOException {
        int ch1 = in.read();
        int ch2 = in.read();
        int ch3 = in.read();
        int ch4 = in.read();
        if ((ch1 | ch2 | ch3 | ch4) < 0)
            throw new EOFException();
        return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
    }
    

    因此,我们可以使用以下公式计算any

    ('3' << 24) + ('3' << 16) + ('3' << 8) + '\n'
    

    我不确定您为什么说 33 有效,因为仅输入 33 并按 Enter 不会为 DataInputStream 提供四个字节,因此它会继续等待另一个字节。您可以按两次Enter,它会打印出来。您的 IDE 可能会添加回车符 \r 以及换行符 \r,因此为什么在 Intellij 上 33 对您有用,而不对我有用。

    【讨论】:

    • 这是对正在发生的事情的一个很好的解释。如果您只想读取用户在&lt;enter&gt; 之前输入的数字,最好的办法是使用BufferedReader.readLine() 将输入作为字符串获取,然后使用String.valueOf 将该字符串转换为整数。
    • 谢谢,OP 应该只使用Scanner ;)
    • 哦,好点,更好用Scanner
    【解决方案2】:

    因为InputStream 读作byte,而不是char

    readInt 将读取 4 byte 以构造 int。但是您的输入 3 只有 1 byte (0x33)。添加行拆分器(\r\n)(0x0d0a),只有3个byte不能构造int。你可以再输入一次,它会打印出来。

    但正确的方法是把 char 读成 char 的方式。您可以使用ReaderScanner

    input = new Scanner(System.in);
    i = input.nextInt();
    

    【讨论】:

    • @mewkie 我说有分线器(0x0d0a)。你可以打印你的any,它不是33,而是(0x33330d0a)。
    猜你喜欢
    • 2013-11-22
    • 1970-01-01
    • 1970-01-01
    • 2020-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-16
    相关资源
    最近更新 更多