黑马程序员技术交流社区

标题: 键盘输入数据的问题 [打印本页]

作者: 鲁柯    时间: 2013-1-9 16:26
标题: 键盘输入数据的问题
本帖最后由 鲁柯 于 2013-1-14 11:19 编辑

到此为止吧,还是没搞清楚DataInputStream接收键盘数据时的问题怎么处理  碰到这类问题就用Scanner吧,省的麻烦


接收键盘输入的数字并打印  有哪些更简单的方法  怎么用DataInputStream的readInt方法接收键盘数据 我用的这个方法有点麻烦了 请大家指点迷津 谢谢
import java.io.*;

public class Test
{
   public static void main(String[] args)
   {
      int[] arr = new int[5];
   
      //对数组各元素进行赋值
      for (int x=0; x<arr.length; x++)
      {
         //定义缓冲区,用于存放键盘录入数据
         //具体定多少字节还不清楚,实验了一会,感觉8个还可以吧,
         //再少数字稍大点就挂,再大点也没多大关系
         byte[] buf = new byte[8];
         int len = 0;   //len用于存放键盘录入的字符个数
         try
         {
            len = System.in.read(buf);   //开始读取键盘录入数据
            //对键盘录入数据进行转换,转为int类型,费了好大工夫才完成
            //键盘录入数据是字节流,看到DataInputStream可以一次读入一个Int数据
            //但没成功,就换了这样一个方法,将存入缓冲区的键盘数据转成字符串再转成数字
            arr[x] = new Integer(new String(buf, 0, len-2));//这里的len长度包含数字输入后按的回车键\r\n
            System.out.println(arr[x]);
         }
         catch (IOException e)
         {
            e.printStackTrace();
         }
                  
      }   
   }
}
/*******************************************
   try
   {
      //接收从键盘输入的一个整数
      //查文档知读一个整数的方法在DataInputStream中
      int num = new DataInputStream(System.in).readInt();
      
      //将从键盘接收到的数字存入数组中
      arr[x] = num;
      //?????这个地方怎么得到的不是想要的数字呢??
      System.out.println(arr[x]);
   }
用上面的方法接收键盘数字得到的结果???
22
842140938
15
825560330
10
825232650
11
825298186
0
1
806160945
*/
作者: 何竹冬    时间: 2013-1-9 16:37
你好
可以使用Scanner类啊,直接读取基本数据类型
Scanner scan = new Scanner(System.in);
while(scan.hasNextInt())
{
  System.out.pirntln(scan.nextInt());
}
作者: 鲁柯    时间: 2013-1-9 16:50
何竹冬 发表于 2013-1-9 16:37 你好 可以使用Scanner类啊,直接读取基本数据类型 Scanner scan = new Scanner(System.in);

受教了,一直想着stream了, 不知道还有这么一个对象  
谢谢指点
作者: 黄嵘才    时间: 2013-1-9 17:21
java中dataoutputstream和datainputstream必须成对使用!!
作者: 黑马吕世成    时间: 2013-1-10 10:03
DataInput适用于读取用接口 DataOutput 的 writeInt 方法写入的字节。

因为这个流读取的是二进制流,读取数据时查表了,必须用write进行写入操作,下面我改了下 你看看吧!这就像编码解码吧,我也不是很明白个中缘由。
你如果明白了一定要分享下啊!

QQ截图20130110095901.png (11.86 KB, 下载次数: 95)

QQ截图20130110095901.png

作者: 鲁柯    时间: 2013-1-10 19:37
黑马吕世成 发表于 2013-1-10 10:03 DataInput适用于读取用接口 DataOutput 的 writeInt 方法写入的字节。 因为这个流读取的是二进制流,读取 ...

试来试去越试头越大  应该是把回车换行也加上混在里边解析了吧
把最下边一行注释后好像可以用了,但又发现新问题 直接输两位数正常 输一位数要按两次回车 再多位数回车数有二有三
还有一个致命问题 其他字母、符号都可以接收并输出 并且数字个数好像无限制 int那能装那么大的数
搞不懂啊

作者: 何伟    时间: 2013-1-10 23:37
{:soso_e103:}
不是亦Scanner这个类么?
Scanner sc = new Scanner(System.in);
在用sc调用next这些方法就ok了
楼主可以去看看API
作者: 鲁柯    时间: 2013-1-11 09:13
何伟 发表于 2013-1-10 23:37 不是亦Scanner这个类么? Scanner sc = new Scanner(System.in); 在用sc调用next这些方法就ok ...

Scanner这个类确实好用 但用DataStream怎么会出现上边说的情况呢 用它读int怎么还能接受其他字符和符号  数字长度还好像没有限制?
作者: 鲁柯    时间: 2013-1-11 09:14
何伟 发表于 2013-1-10 23:37 不是亦Scanner这个类么? Scanner sc = new Scanner(System.in); 在用sc调用next这些方法就ok ...

Scanner这个类确实好用 但用DataStream怎么会出现上边说的情况呢 用它读int怎么还能接受其他字符和符号  数字长度还好像没有限制?
作者: 鲁柯    时间: 2013-1-11 09:39
手机发帖都附送一份吗?
不敢再发了
作者: 鲁柯    时间: 2013-1-11 09:40
手机发帖都附送一份吗?
不敢再发了
作者: 夏振博    时间: 2013-1-12 02:10
搞不懂你问的什么,怎么会出问题呢?字符串和整数都行啊!
  1. public class Test {
  2.         public static void main(String[] agrs) {
  3.                 for (int i = 0; i < 5; i++) {
  4.                         Scanner in = new Scanner(System.in);
  5.                         System.out.println("请输入你的姓名:");
  6.                         String name = in.nextLine();
  7.                         in = new Scanner(System.in);
  8.                         System.out.println("请输入你的年龄:");
  9.                         int age = 0;
  10.                         try {
  11.                                 String ss = in.nextLine();
  12.                                 age = Integer.parseInt(ss);
  13.                         } catch (Exception e) {

  14.                                 System.out.println("你输入错误!请输入整数!");
  15.                                 System.out.println("请输入你的年龄:");
  16.                                 String ss = in.nextLine();
  17.                                 age = Integer.parseInt(ss);
  18.                         }
  19.                         System.out.println(name);
  20.                         System.out.println(age);
  21.                 }
  22.         }
  23. }
复制代码

作者: 鲁柯    时间: 2013-1-14 11:15
arno942 发表于 2013-1-12 02:10
搞不懂你问的什么,怎么会出问题呢?字符串和整数都行啊!

Scanner的确好用  现在不明白的是DataInputStream接受键盘输入时出的问题,你把上面的代码运行一下就知道问题了
作者: 黑马吕世成    时间: 2013-1-14 16:53
鲁柯 发表于 2013-1-10 19:37
试来试去越试头越大  应该是把回车换行也加上混在里边解析了吧
把最下边一行注释后好像可以用了,但又发 ...

好吧,之前我一直没上网也就没看到回复。对于出现的问题我一一给你讲下吧。

下面是该方法的源码:不难发现其实就是用字节流没读入四个节输出一个int,因为int就是四个字节。因为读取的是字节,而任何文件都是字节组成的,所以这里肯定有一个问题就是,字节流可以读取任意的文件,无法判断你提供的数据是否是int了,当然导致的结果就是来什么读什么然后输出什么。这个好理解了吧!其实你查看其他的读取基本数据类型long,char等都是一个原理,基本数据类型是几个字节就读取几个字节然后返回。如:char一个字节,那么他就只有一个in.read(),然后返回。

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

知道了读取数据的原理,开始说从命令行读取数据了。其实从命令行输入的任何内容都是以字符串的形式存在,我们从主函数的参数列表就可以发现(String args[])。所以表面上你是输入了一个数字,如:11,123。但实际上是字符串,字符串和整数在这里的区别就很大了,因为占用的内存空间不一样。
       如属入:11 ,字符串——占用两个字节;整数——占用四个字节。
还有最后一点我需要说明的就是读取内容的问题:
    一般我们典型的读取命令行输入用的是BufferedReader:Reader bufr = new BufferedReader(new InputStreamReader(System.in)) ;通过readerLine方法读取。
因为readLine方法可以读取整行,将Enter将屏蔽了(我姑且这么说,底层怎么实现视频里讲的很清楚了!),所以能够一行一行读取。
   但是用DataInputStream就不会这样,他会将你输入的所有字符读入,这里就包含了Enter键,Enter键在windos系统对应的就是字符串/r/n(回车换行两个)。




下面我来解释上图张输入的问题了,因为对enter键也会读取,所以也要注意光标出现的位置。你如果看到这张图你就能自己推出我输入了什么,我想你已经明白了这其中的道理。



图片里我把流程都说了一遍。自己好好看看。如果还不是很清楚可以再qq上一起交流下。(710896696 哈哈,顺便推荐哈自己,装B了!!)

不知道图片你看的清楚不,我不知道会是什么效果。


作者: 黑马吕世成    时间: 2013-1-14 16:55
黑马吕世成 发表于 2013-1-14 16:53
好吧,之前我一直没上网也就没看到回复。对于出现的问题我一一给你讲下吧。

下面是该方法的源码:不难发 ...

额 ,版面怎么变成这样,你先把文字看完,最后再看图片,我插了一张结果,另外一张是对结果的分析!!




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2