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