黑马程序员技术交流社区

标题: 用数组读取键盘录入并加入健壮性判断 [打印本页]

作者: 小泽    时间: 2015-3-1 11:44
标题: 用数组读取键盘录入并加入健壮性判断
是这样的,学到IO流的时候毕老师留的题,要求用数组来实现读取键盘录入这个代码。
我在做完后又加入健壮性判断。
代码如下:
  1. public class ReadKey {
  2.         /**
  3.          * @param args
  4.          * @throws IOException
  5.          */
  6.         public static void main(String[] args) throws IOException {
  7.                 readKey_3();       
  8.         }
  9.         /**
  10.          * @throws IOException
  11.          *
  12.          */
  13.         public static void readKey_3() throws IOException {
  14.                 final int ONEKB = 1024;
  15.                 char[] str = new char[ONEKB];//定义一个字符数组长度为1024的数组,长度溢出的错误请忽略,我认为已经够大了。
  16.                
  17.                 System.out.println("请输入一串小写字母:");
  18.                 InputStream in = System.in;//输入流

  19.                 int ch = 0;//读取的字节
  20.                 int index = 0;//数组的指针
  21.                 while ((ch = in.read()) != -1) {
  22.                         if((ch>=97&ch<=122)||(ch==10||ch==13)){//健壮性判断
  23.                                
  24.                                 if (ch == '\r')
  25.                                         continue;
  26.                                 if (ch == '\n') {//当读取到回车时,把数组中的字符转化为字符串存储。
  27.        
  28.                                         String temp = new String(str, 0, index);
  29.        
  30.                                         if ("over".equals(temp)) {
  31.        
  32.                                                 System.out.println("程序已终止");
  33.                                                 break;
  34.                                         }
  35.                                         System.out.println("对应的字母大写为:" + temp.toUpperCase());//输出大写字符串。
  36.                                         System.out.println("请输入一串小写字母或输入over结束程序。");
  37.                                         index = 0;
  38.                                 }
  39.                                 else {
  40.                                         str[index] = (char) ch;//把读取到的数据转化为字节存储到数组中。
  41.                                         index++;
  42.                                 }
  43.                         }
  44.                         else{
  45.                                 System.out.println("输入不合法请重新输入:");
  46.                         }
  47.                 }
  48.         }
复制代码
问题来了,请看图:
我也不知道图在哪。
问题是输入不合法时候还会继续循环并输出能变成大写的字符,但是我的需求是一旦输入不合法就停止当前循环并提示重新输入并开始循环,可能有些墨迹,看着理解。多多包涵,谢了各位。


捕获.JPG (58.85 KB, 下载次数: 19)

捕获.JPG

作者: 小泽    时间: 2015-3-1 11:45
召唤大神。。。。。。。。。。。。。。。。。。。。。。。。。
作者: Hsidar    时间: 2015-3-1 12:00
其实控制台输入时是有缓存的,只有输入完成点击Enter键或者其他控制键的时候才会将数据提交给程序,输入一个立马判读在这里不行。
作者: alvis2015    时间: 2015-3-1 12:08
本帖最后由 alvis2015 于 2015-3-1 12:28 编辑

你while语句里面的判断条件是一个字符一个字符判断的,比如你输入了12asdf,程序先判断1,发现不是字母,提示你的输入有误
这个时候ch变量的下一个字符是2,又不是字母,有提示输入有误请重新输入,然后ch的下一个字符是a,发现是字母,就变成大写保存到数组中了
之后的sdf是一个道理,当f判断完成后,ch继续读入,发现是换行,然后就输出了数组中的大写字母。解决方法:如果碰到非法字符,则跳过输入流中剩余的字符,不再判断,而是等待用户输入,代码如下:
  1. import java.io.IOException;
  2. import java.io.InputStream;

  3. public class test {
  4.         /**
  5.          * @param args
  6.          * @throws IOException
  7.          */
  8.         public static void main(String[] args) throws Exception {
  9.                 readKey_3();        
  10.         }
  11.         /**
  12.          * @throws IOException
  13.          *
  14.          */
  15.         public static void readKey_3() throws IOException {
  16.                 final int ONEKB = 1024;
  17.                 char[] str = new char[ONEKB];//定义一个字符数组长度为1024的数组,长度溢出的错误请忽略,我认为已经够大了。
  18.                
  19.                 System.out.println("请输入一串小写字母:");
  20.                 InputStream in = System.in;//输入流

  21.                 int ch = 0;//读取的字节
  22.                 int index = 0;//数组的指针
  23.                 int count = 0;
  24.                 while ((ch = in.read()) != -1) {
  25.                         if((ch>=97&ch<=122)||(ch==10||ch==13)){//健壮性判断
  26.                                 
  27.                             if (ch == '\r')
  28.                                    continue;
  29.                                 
  30.                                 if (ch == '\n') {//当读取到回车时,把数组中的字符转化为字符串存储。
  31.         
  32.                                         String temp = new String(str, 0, index);
  33.                                       
  34.         
  35.                                         if ("over".equals(temp)) {
  36.         
  37.                                                 System.out.println("程序已终止");
  38.                                                 break;
  39.                                         }
  40.                                         System.out.println("对应的字母大写为:" + temp.toUpperCase());//输出大写字符串。
  41.                                         System.out.println("请输入一串小写字母或输入over结束程序。");
  42.                                         index = 0;
  43.                                 }
  44.                                 else {
  45.                                         str[index] = (char) ch;//把读取到的数据转化为字节存储到数组中。
  46.                                         index++;
  47.                                 }
  48.                         }
  49.                         else{
  50.                                 System.out.println("输入不合法请重新输入:");
  51.                                 in.skip(in.available());  //如果输入不合法,则跳过剩余可读字符,这样流中的指针就走到头了,因为下面没有字符了,所入进入阻塞状态等待用户输入           
  52.                         }
  53.                 }
  54.         }
  55. }
复制代码




作者: shuren2015    时间: 2015-3-1 12:23
你这种按字节来读的难改啊,我再想想
作者: shuren2015    时间: 2015-3-1 12:33
你自己看下,忙着写技术博客,我就不说明了
  1. package daliytest;

  2. import java.io.*;

  3. public class ReadKey {
  4.     /**
  5.      * @param args
  6.      * @throws IOException
  7.      */
  8.     public static void main(String[] args) throws IOException {
  9.             readKey_3();        
  10.     }
  11.     /**
  12.      * @throws IOException
  13.      *
  14.      */
  15.     public static void readKey_3() throws IOException {
  16.             final int ONEKB = 1024;
  17.             char[] str = new char[ONEKB];//定义一个字符数组长度为1024的数组,长度溢出的错误请忽略,我认为已经够大了。
  18.             
  19.             System.out.println("请输入一串小写字母:");
  20.             InputStream in = (InputStream) System.in;//输入流
  21.             
  22.             int ch = 0;//读取的字节
  23.             int index = 0;//数组的指针
  24.           w: while(true){
  25.             while ((ch = in.read()) != -1) {
  26.                     if((ch>=97&ch<=122)||(ch==10||ch==13)){//健壮性判断
  27.                            
  28.                             if (ch == '\r')
  29.                                     continue;
  30.                             if (ch == '\n') {//当读取到回车时,把数组中的字符转化为字符串存储。
  31.    
  32.                                     String temp = new String(str, 0, index);
  33.    
  34.                                     if ("over".equals(temp)) {
  35.    
  36.                                             System.out.println("程序已终止");
  37.                                             break w;
  38.                                     }
  39.                                     System.out.println("对应的字母大写为:" + temp.toUpperCase());//输出大写字符串。
  40.                                     System.out.println("请输入一串小写字母或输入over结束程序。");
  41.                                     index = 0;
  42.                                 
  43.                             }
  44.                             else {
  45.                                     str[index] = (char) ch;//把读取到的数据转化为字节存储到数组中。
  46.                                     index++;
  47.                             }
  48.                     }
  49.                     else{
  50.                             System.out.println("输入不合法请重新输入:");
  51.                              while((ch=in.read())!=-1){
  52.                                      if(ch=='\n'){
  53.                                              break;
  54.                                      }
  55.                              }
  56.                              break;
  57.                     }
  58.             }
  59.           }
  60.     }
  61. }
复制代码

作者: sofeel    时间: 2015-3-1 13:11
  1. package pre;

  2. import java.io.IOException;
  3. import java.io.InputStream;

  4. public class ReadKey {
  5.         /**
  6.          * @param args
  7.          * @throws IOException
  8.          */
  9.         public static void main(String[] args) throws IOException {

  10.                 readKey_3();
  11.         }

  12.         /**
  13.          * if判断一般反向运用,显得条例清晰(个人觉得)。
  14.          *
  15.          * 你的健壮性判断,是为了确保输入的正确性,即整个字符串中全为小写字符。正确的输入格式:"请输入一串小写字母"。
  16.          * 所以,对录入的单个字符判断没有意义,而应该是对字符串中的每个字符判断。
  17.          * 修改:
  18.          * 1,在字符串,有一个字符不是小写,就判定出错。
  19.          * 2,提示信息是对字符串的提示,而不是单个字符。
  20.          *
  21.          * 判断可以用两种方式实现:
  22.          * 1,采用if判断保证输入正确;
  23.          * 2,采用正则匹配保证输入正确。
  24.          *
  25.          * 这里就用第一种吧,我在你的代码基础上修改。等你学了正则,你也试下第二种,很爽的。
  26.          *
  27.          */
  28.         public static void readKey_3() throws IOException {
  29.                
  30.                 final int ONEKB = 1024;
  31.                 char[] str = new char[ONEKB];

  32.                 System.out.println("请输入一串小写字母:");
  33.                 InputStream in = System.in;

  34.                 int ch = 0;
  35.                 int index = 0;
  36.                
  37.                 while ((ch = in.read()) != -1)
  38.                 {
  39.                         if (ch == '\r')
  40.                                 continue;
  41.                         if (ch == '\n')
  42.                         {// 当读取到回车时,把数组中的字符转化为字符串存储。

  43.                                 String temp = new String(str, 0, index);

  44.                                 if ("over".equals(temp))
  45.                                 {
  46.                                         System.out.println("程序已终止");
  47.                                         break;
  48.                                 }
  49.                                

  50.                                 // 健壮性判断
  51.                                 boolean flag=true;
  52.                                 for(int x=0;x<temp.length();x++)//遍历字符串,判断每一个字符是否为小写,只要有一个不是,输入格式就不对
  53.                                 {
  54.                                         if (!(temp.charAt(x)>='a' && temp.charAt(x)<='z'))//有一个字符不对,就跳出循环,给出提示信息(而这一点在键盘输入时无法做到)
  55.                                         {
  56.                                                 flag=false;
  57.                                                 break;
  58.                                         }
  59.                                                
  60.                                 }
  61.                                 if(flag==false)
  62.                                 {
  63.                                         System.out.println("输入不合法请重新输入:");
  64.                                         continue;//格式不对,就重新开始读。不执行后面代码
  65.                                 }
  66.                                        
  67.                                 //大写转换
  68.                                 System.out.println("对应的字母大写为:" + temp.toUpperCase());
  69.                                 System.out.println("请输入一串小写字母或输入over结束程序。");
  70.                                 index = 0;
  71.                         }
  72.                         else
  73.                         {
  74.                                 str[index] = (char) ch;
  75.                                 index++;
  76.                         }
  77.                 }
  78.         }
  79. }
复制代码

作者: alvis2015    时间: 2015-3-1 13:18
sofeel 发表于 2015-3-1 13:11

测试了吗?
作者: sofeel    时间: 2015-3-1 13:55
alvis2015 发表于 2015-3-1 13:18
测试了吗?


测过。
作者: 小泽    时间: 2015-3-1 14:09
alvis2015 发表于 2015-3-1 12:08
你while语句里面的判断条件是一个字符一个字符判断的,比如你输入了12asdf,程序先判断1,发现不是字母,提 ...

谢谢。因为我刚学到io,所以你下边用的方法我还没学过,但是看注释还是能看出一定解决了的,就是那个count貌似没啥用。
作者: 小泽    时间: 2015-3-1 14:14
shuren2015 发表于 2015-3-1 12:33
你自己看下,忙着写技术博客,我就不说明了

首先谢谢,然后你这个break后面多个w,之后就是我验证下发现确实输入不合法会跳出,但是随之而来的是程序结束,不再重新循环,所以不符合要求。
作者: 小泽    时间: 2015-3-1 14:19
sofeel 发表于 2015-3-1 13:11

谢谢哥们  不过还是不行 看图

捕获1.JPG (44.68 KB, 下载次数: 20)

捕获1.JPG

作者: 小泽    时间: 2015-3-1 14:23
alvis2015 发表于 2015-3-1 12:08
你while语句里面的判断条件是一个字符一个字符判断的,比如你输入了12asdf,程序先判断1,发现不是字母,提 ...

又测试了一下  是O的

捕获2.JPG (78.42 KB, 下载次数: 14)

捕获2.JPG

作者: sofeel    时间: 2015-3-1 14:30
本帖最后由 sofeel 于 2015-3-1 14:34 编辑
小泽 发表于 2015-3-1 14:19
谢谢哥们  不过还是不行 看图

不可能啊
你看我的测试:
如果,你想输错之后,继续输入,就用continue;
若果,你想输错之后,就终止输入,用return.


测试.gif (16.28 KB, 下载次数: 29)

测试.gif

作者: 小泽    时间: 2015-3-1 14:56
sofeel 发表于 2015-3-1 14:30
不可能啊
你看我的测试:
如果,你想输错之后,继续输入,就用continue;

哥们 你再测试下 你先输入正确的 再输入错误的 再输入正确的 会提示输入不合法。
我看了下,发现是指针没有重置,在判断代码块中加入index=0;发现ok了。

if(flag==false)
                        {
                                System.out.println("输入不合法请重新输入:");
                                index = 0;
                                continue;//格式不对,就重新开始读。不执行后面代码
                        }
作者: 小泽    时间: 2015-3-1 15:05
shuren2015 发表于 2015-3-1 12:33
你自己看下,忙着写技术博客,我就不说明了

啊,是我的错,我没看见前面那个w,从新检验了一下,没问题,ok的。就是不知道你的那个while前面的w:是什么意思,没看见过啊,什么用法?
作者: sofeel    时间: 2015-3-1 15:43
  1. package pre;

  2. import java.io.IOException;
  3. import java.io.InputStream;

  4. public class ReadKey {
  5.         /**
  6.          * @param args
  7.          * @throws IOException
  8.          */
  9.         public static void main(String[] args) throws IOException {

  10.                 readKey_3();
  11.         }

  12.        
  13.         public static void readKey_3() throws IOException {
  14.                
  15.                 final int ONEKB = 1024;
  16.                 char[] str = new char[ONEKB];

  17.                 System.out.println("请输入一串小写字母:");
  18.                 InputStream in = System.in;

  19.                 int ch = 0;
  20.                 int index = 0;
  21.                
  22.         to:        while ((ch = in.read()) != -1)
  23.                 {
  24.                        
  25.                        
  26.                         //获取字符串
  27.                         if (ch == '\r')
  28.                                 continue;
  29.                         if (ch == '\n')
  30.                         {// 当读取到回车时,把数组中的字符转化为字符串存储。
  31.                                
  32.                                 String temp=new String(str,0,index);
  33.                                
  34.                                 if ("over".equals(temp))
  35.                                 {
  36.                                         System.out.println("程序已终止");
  37.                                         break;
  38.                                 }
  39.                                

  40.                                 // 格式判断
  41.                                 for(int x=0;x<temp.length();x++)
  42.                                 {
  43.                                         if ((temp.charAt(x)>='a' && temp.charAt(x)<='z'))
  44.                                         {
  45.                                                 //大写转换
  46.                                                 System.out.println("对应的字母大写为:" + temp.toUpperCase());
  47.                                                 System.out.println("请输入一串小写字母或输入over结束程序。");
  48.                                                 index=0;
  49.                                                 continue to;
  50.                                         }
  51.                                         else
  52.                                         {
  53.                                                 System.out.println("输入不合法请重新输入:");
  54.                                                 index=0;
  55.                                                 continue to;//格式不对,就重新开始读。不执行后面代码
  56.                                         }
  57.                                        
  58.                                 }
  59.                         }
  60.                         else
  61.                         {
  62.                                 str[index++]=(char)ch;
  63.                                
  64.                         }
  65.                 }
  66.         }
  67. }
复制代码

作者: sofeel    时间: 2015-3-1 15:49
这个验证很实用的。楼主,玲珑心啊,呵呵
作者: sofeel    时间: 2015-3-1 15:55
小泽 发表于 2015-3-1 15:05
啊,是我的错,我没看见前面那个w,从新检验了一下,没问题,ok的。就是不知道你的那个while前面的w:是 ...

那个就是标记。
continue和break都可以用的,可以指定要跳的是那个循环体。而不用标记,一般默认是跳出当前循环体。
作者: 小泽    时间: 2015-3-1 17:14
sofeel 发表于 2015-3-1 15:55
那个就是标记。
continue和break都可以用的,可以指定要跳的是那个循环体。而不用标记,一般默认是跳出当 ...

哦,受教了,我还真不知道这个东西。谢了哥们。




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