Java编程那些事儿89——读取控制台输入

陈跃峰

11.3.2 读取控制台输入

         前面介绍了使用IO类实现文件读写的示例,其实在很多地方还需要使用到IO类,这里再以读取控制台输入为例子来介绍IO类的使用。

         控制台(Console)指无图形界面的程序,运行时显示或输入数据的位置,前面的介绍中可以使用System.out.println将需要输出的内容显示到控制台,本部分将介绍如何接受用户在控制台中的输入。

         使用控制台输入是用户在程序运行时和程序进行交互的一种基础手段,这种手段是Windows操作系统出现以前,操作系统位于DOS时代时,用户和程序交互的主要手段。当然,现在这种交互的方式已经被图形界面(GUI)程序取代了。

         在读取控制台操作中,操作系统在用户在控制台输入内容,并按回车键提交以后,将用户提交的内容传递给Java运行时系统,Java运行时系统将用户输入的信息构造成一个输入流对象——System.in,在程序员读取控制台输入时,只需要从该流中读取数据即可。至于构造流System.in的过程对于程序员来说是透明的。

         查阅JDK API可以发现,System类中的静态属性in是InputStream类型的对象,可以按照输入流的读取方法读取即可。

         下面的示例代码实现了输入“回显”的功能,即将用户输入的内容重新显示到控制台,示例代码如下:

/**
 * 读取控制台输入,并将输入的内容显示到控制台
 */
public class ReadConsole1 {
         public static void main(String[] args) {
                   try{
                            //提示信息
                            System.out.println("请输入:");
                            //数组缓冲
                            byte[] b = new byte[1024];
                            //读取数据
                            int n = System.in.read(b);
                            //转换为字符串
                            String s = new String(b,0,n);
                            //回显内容
                            System.out.println("输入内容为:" + s);
                   }catch(Exception e){}
         }
}

         在该示例代码中,从System.in中读取出用户的输入,然后将用户输入的内容转换为字符串s,然后输出该字符串的内容即可。

         下面实现一个简单的逻辑,功能为:回显用户在控制台输入的内容,当用户输入quit时程序运行结束。实现的代码如下:

                

/**
 * 读取控制台输入
 * 循环回显内容,当输入quit时退出程序
 */
public class ReadConsole2 {
         public static void main(String[] args) {
                   //数组缓冲
                   byte[] b = new byte[1024];
                   //有效数据个数
                   int n = 0;
                   try{
                            while(true){
                                     //提示信息
                                     System.out.println("请输入:");
                                     //读取数据
                                     n = System.in.read(b);
                                     //转换为字符串
                                     String s = new String(b,0,n - 2);
                                     //判断是否是quit
                                     if(s.equalsIgnoreCase("quit")){
                                               break;  //结束循环
                                     }
                                     //回显内容
                                     System.out.println("输入内容为:" + s);
                            }
                   }catch(Exception e){}
         }
}

         在该示例代码中,加入了一个while循环,使得用户的输入可以进行多次,在用户输入时,送入输入流的内容除了用户输入的内容以外,还包含”/r/n”这两个字符,所以在将输入的内容和quit比较时,去掉读出的最后2个字符,将剩余的内容转换为字符串。

         最后是一个简单的《掷骰子》的控制台小游戏,在该游戏中,玩家初始拥有1000的金钱,每次输入押大还是押小,以及下注金额,随机3个骰子的点数,如果3个骰子的总点数小于等于9,则开小,否则开大,然后判断玩家是否押对,如果未押对则扣除下注金额,如果押对则奖励和玩家下注金额相同的金钱。该程序的示例代码如下:

             

/**
 * 掷骰子游戏实现
 */
public class DiceGame {
         public static void main(String[] args) {
                   int money = 1000; //初始金钱数量
                   int diceNum = 0; // 掷出的骰子数值和
                   int type = 0; // 玩家押的大小
                   int cMoney = 0; // 当前下注金额
                   boolean success; // 胜负
                   // 游戏过程
                   while (true) {
                            // 输入大小
                            System.out.println("请押大小(1代表大,2代表小):");
                            type = readKeyboard();
                            // 校验
                            if (!checkType(type)) {
                                     System.out.println("输入非法,请重新输入!");
                                     continue;
                            }
                            // 输入下注金额
                            while(true){
                                     System.out.println("你当前的金钱数量是"
                                                                 + money + "请下注:");
                                     cMoney = readKeyboard();
                                     // 校验
                                     if (!checkCMoney(money,cMoney)) {
                                               System.out.println("输入非法,请重新输入!");
                                               continue;
                                     }else{
                                               break;
                                     }
                            }
                            // 掷骰子
                            diceNum = doDice();
                            // 判断胜负
                            success = isSuccess(type,diceNum);
                            // 金钱变化
                            money = changeMoney(money,success,cMoney);
                            // 游戏结束
                            if(isEnd(money)){
                                     System.out.println("你输了,bye!");
                                     break;
                            }
                   }
         }
 
         /**
          * 读取用户输入
          * @return 玩家输入的整数,如果格式非法则返回0
          */
         public static int readKeyboard() {
                   try {
                            // 缓冲区数组
                            byte[] b = new byte[1024];
                            // 读取用户输入到数组b中,
                            // 读取的字节数量为n
                            int n = System.in.read(b);
                            // 转换为整数
                            String s = new String(b, 0, n - 2);
                            int num = Integer.parseInt(s);
                            return num;
                   } catch (Exception e) {}
                   return 0;
         }
 
         /**
          * 押的类型校验
          * @param type  类型
          * @return true代表符合要求,false代表不符合
          */
         public static boolean checkType(int type) {
                   if (type == 1 || type == 2) {
                            return true;
                   } else {
                            return false;
                   }
         }
 
         /**
          * 校验下注金额是否合法
          * @param money   玩家金钱数
          * @param cMoney  下注金额
          * @return true代表符合要求,false代表不符合要求
          */
         public static boolean checkCMoney(int money, int cMoney) {
                   if (cMoney <= 0) {
                            return false;
                   } else if (cMoney <= money) {
                            return true;
                   } else {
                            return false;
                   }
         }
 
         /**
          * 掷骰子
          * @return 骰子的数值之和
          */
         public static int doDice() {
                   int n = (int) (Math.random() * 6) + 1;
                   int n1 = (int) (Math.random() * 6) + 1;
                   int n2 = (int) (Math.random() * 6) + 1;
                   // 输出随机结果
                   System.out.println("庄家开:" + n + " " + n1 + " " + n2);
                   return n + n1 + n2;
         }
 
         /**
          * 胜负判断
          * @param type  用户输入类型
          * @param diceNum   骰子点数
          * @return true代表赢,false代表输
          */
         public static boolean isSuccess(int type, int diceNum) {
                   // 计算庄家类型
                   int bankerType = 0;
                   if (diceNum <= 9) {
                            bankerType = 2;
                            System.out.println("庄家开小!");
                   } else {
                            bankerType = 1;
                            System.out.println("庄家开大!");
                   }
                   if (bankerType == type) { // 赢
                            return true;
                   } else { // 输
                            return false;
                   }
         }
 
         /**
          * 金钱变化
          * @param money 用户钱数
          * @param success 胜负
          * @param cMoney 下注金额
          * @return 变化以后的金钱
          */
         public static int changeMoney(int money, boolean success, int cMoney) {
                   if (success) {
                            money += cMoney;
                   } else {
                            money -= cMoney;
                   }
                   System.out.println("剩余金额:" + money);
                   return money;
         }
 
         /**
          * 判断游戏是否结束
          * @param money 玩家金钱
          * @return true代表结束
          */
         public static boolean isEnd(int money) {
                   return money <= 0;
         }
}