Java中輸入完成後終止掃描器的
1. 引言
在編寫從控制台讀取輸入的 Java 程式時,我們會用到Scanner類別。它簡單、強大且靈活,足以處理各種類型的輸入,包括整數、雙精度浮點數和字串。然而,開發者在使用Scanner物件時面臨的最常見挑戰之一,是如何在任務完成後停止讀取輸入。
假設我們需要讀取多行輸入,處理完畢後優雅地終止程式。乍一看,似乎按幾次Return鍵就能告訴程式輸入已經結束。但實際上,程式會繼續等待更多輸入,因為它本身並不知道我們何時停止輸入。
在本教學中,我們將探討如何在輸入完成後終止 Java Scanner 。首先,我們將討論終止scanner的不同策略,並查看演示正確方法的程式碼範例。此外,我們將分析某些基本嘗試失敗的原因。最後,我們將總結編寫簡潔、有效率的 Java 輸入處理程式碼的最佳實務。
2. 終止Scanner類
連接到System.in Scanner會持續等待輸入。從程式碼角度來看,只要使用者沒有明確指示它停止,它就假定可能還會有更多輸入。按下Return鍵僅表示一行結束,而不是整個輸入流的結束。
例如,我們考慮一個簡單的Scanner終止情況:
import java.util.Scanner;
public class SampleScanner {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
try {
while (scan.hasNextLine()) {
String line = scan.nextLine().toLowerCase();
System.out.println(line);
}
} finally {
scan.close();
}
}
}
乍一看,邏輯似乎很簡單。循環會不斷讀取並列印每一行,直到沒有更多行可讀為止。然而,除非程式接收到明確的輸入結束訊號,否則hasNextLine()函數會一直回傳 `true` 。這就是為什麼用戶多次按下Return時,循環不會自動終止的原因。
3. Scanner終止注意事項
值得注意的是,在使用Scanner時,應注意其終止方式。
3.1. 關閉掃描器類
使用 Scanner 時,為了避免記憶體洩漏,請務必關閉資源。但是,如果Scanner正在讀取System.in中的數據,關閉它也會關閉底層的輸入流,而該輸入流無法重新開啟。
這可能會導致更多錯誤。
3.2. 優雅終止與強制退出
有些範例展示如何使用 ` System.exit(0)立即終止程式。雖然這種方法可行,但過於簡單粗暴。更簡潔的方法是跳出循環,讓程式自然地結束。
在多執行緒情況下,這一點尤其重要。
4. 錯誤地使用==運算子來檢查輸入
如果我們嘗試直接使用==比較輸入,或者透過檢查輸入是否等於空字串來終止Scanner輸入,通常都會失敗。但專門針對空字串的情況是例外。
例如,讓我們考慮一下SampleScannerScan.java中的scan.nextLine比較:
import java.util.Scanner;
public class SampleScannerScan {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
try {
while (scan.hasNextLine()) {
String line = scan.nextLine();
if (line == null) {
System.out.println("Exiting program (null check)...");
System.exit(0);
}
System.out.println("Input was: " + line);
}
} finally {
scan.close();
}
}
}
==運算子檢查的是兩個引用是否指向同一個對象,而不是兩個字串的內容是否相等。因此,即使兩個字串包含相同的字符, ==也可能返回false 。要正確比較字串,我們需要使用.equals()或.isEmpty() 。
5. 使用檔案結束符 (EOF) 標記
關閉Scanner最直接的方法是讓使用者使用作業系統的 EOF 標記來指示輸入結束。在類 Unix 系統中,EOF 標記是一個控製字符,可以透過CTRL + D表示;而在 Windows 系統中,則使用CTRL + Z當發送 EOF 標記時, hasNextLine()傳回false ,循環自然結束。
讓我們來看看EOFExample.java中的範例程式碼,它示範了 EOF 的用法:
import java.util.Scanner;
public class EOFExample {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
try {
System.out.println("Enter text (press CTRL+D on Unix/Mac or CTRL+Z on Windows to end):");
while (scan.hasNextLine()) {
String line = scan.nextLine();
System.out.println("You entered: " + line);
}
System.out.println("End of input detected. Program terminated.");
} finally {
scan.close();
}
}
}
這種方法無需修改程式碼即可實現,但前提是使用者知道如何發送 EOF 訊號。然而,這可能並非總是最友善的用戶選擇。
5. 使用哨兵值
另一種常見的優雅終止Scanner的方法是定義一個特殊的關鍵字來指示使用者已完成操作。這個哨兵值可以是簡單的exit 、 quit ,甚至是像##這樣的符號。程式可以逐行檢查,當遇到符合的哨兵值時,便會優雅地終止。
讓我們修改SampleScannerSentinel.java文件,使其能夠檢查Scanner是否已終止:
import java.util.Scanner;
public class SampleScannerSentinel {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
try {
while (scan.hasNextLine()) {
String line = scan.nextLine().toLowerCase();
if (line.equals("exit")) {
System.out.println("Exiting program...");
break;
}
System.out.println(line);
}
} finally {
scan.close();
}
}
}
在這個版本中,輸入exit會立即結束循環。這種方法更簡單,因為使用者清楚地知道如何發出完成信號。
6. 使用do-while循環
實作Scanner的另一種方法是使用do-while循環。這種結構確保在檢查終止條件之前至少讀取一行。讓我們來看看SampleScanner.java檔案中的程式碼,但這次使用do-while循環( DoWhileScanner.java ):
import java.util.Scanner;
public class DoWhileScanner {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String input;
do {
input = sc.nextLine();
System.out.println(input);
} while (!input.equals("exit"));
sc.close();
}
}
在這個範例中,程式會一直循環,直到使用者輸入指示詞「 exit為止。它簡潔明了,確保用戶輸入能夠立即處理。
7. 結論
本文介紹如何在 Java 中輸入完成後終止Scanner 。最有效的兩種方法是使用系統 EOF 標記或定義一個哨兵值(例如exit 。雖然 EOF 標記效率很高,但哨兵值方法通常能為使用者提供更清晰的體驗。此外,我們也了解了為什麼像檢查null或使用==的簡單方法會失敗。