Java 零基础教程

Java 扫描器 (Scanner) 与控制台输入

从控制台读取输入是编程中的一项基本技能。它允许你的程序与用户交互、接收数据并根据输入执行操作。在 Java 中,Scanner 类提供了一种便捷的方法来读取控制台中的各种输入类型,如整数、浮点数、字符串等。

本章将涵盖使用 Scanner 类读取控制台输入的要点,包括如何创建 Scanner 对象、读取不同数据类型、处理潜在错误以及关闭扫描器以防止资源泄漏。

1. 理解 Scanner 类

Scanner 类位于 java.util 包中,它提供了使用正则表达式解析基本类型和字符串的方法。要使用 Scanner 类,你首先需要创建一个 Scanner 对象,通常将其与标准输入流(System.in)相关联,后者代表控制台。

1.1 创建 Scanner 对象

要创建一个从控制台读取数据的 Scanner 对象,请使用以下语法:

import java.util.Scanner; // 导入 Scanner 类

public class InputExample {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in); // 创建 Scanner 对象
        // ... 其余代码
    }
}
  • import java.util.Scanner;:这行代码导入了 Scanner 类。没有它,编译器就不知道 Scanner 是什么。
  • Scanner scanner = new Scanner(System.in);:这行代码创建了一个名为 scanner 的新对象。System.in 参数指定扫描器应从标准输入流(通常是键盘/控制台)读取。

2. 读取不同的数据类型

Scanner 类提供了多种方法来从输入流中读取数据:

  • nextInt():读取一个整数值。
  • nextDouble():读取一个双精度浮点值。
  • nextFloat():读取一个单精度浮点值。
  • nextBoolean():读取一个布尔值。
  • next():读取下一个标记(Token)作为字符串(以空白符分隔)。
  • nextLine():读取整行文本(包括空格)。

2.1 综合示例

import java.util.Scanner;

public class ReadDataTypes {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        System.out.print("请输入一个整数: ");
        int integerValue = scanner.nextInt();

        System.out.print("请输入一个小数: ");
        double doubleValue = scanner.nextDouble();

        System.out.print("请输入一段文字: ");
        // 关键点:消耗掉 nextDouble() 留下的换行符
        scanner.nextLine(); 
        String stringValue = scanner.nextLine();

        System.out.println("整数: " + integerValue);
        System.out.println("小数: " + doubleValue);
        System.out.println("文字: " + stringValue);

        scanner.close(); // 关闭扫描器
    }
}

注意:nextInt()nextDouble() 等方法不会消耗你按下回车键时产生的“换行符”。如果你紧接着调用 nextLine(),它会直接读取那个残留的换行符并返回一个空字符串。因此,通常需要额外调用一次 nextLine() 来“清理”缓冲区。

3. 处理输入不匹配异常 (InputMismatchException)

如果用户输入的类型与预期不符(例如程序要整数,用户输入了字母),Scanner 会抛出 InputMismatchException。你可以使用 try-catch 块来处理它。

import java.util.Scanner;
import java.util.InputMismatchException;

public class InputMismatch {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        try {
            System.out.print("请输入一个整数: ");
            int integerValue = scanner.nextInt();
            System.out.println("你输入了: " + integerValue);
        } catch (InputMismatchException e) {
            System.out.println("输入无效,请输入一个整数。");
            scanner.next(); // 关键:消耗掉无效输入,防止死循环
        } finally {
            scanner.close();
        }
    }
}

4. 使用分隔符 (Delimiters)

默认情况下,Scanner 使用空白符(空格、制表符、换行符)作为分隔符。你可以使用 useDelimiter() 修改它。

import java.util.Scanner;

public class DelimiterExample {
    public static void main(String[] args) {
        String input = "苹果,香蕉,橘子";
        Scanner scanner = new Scanner(input);
        scanner.useDelimiter(","); // 设置逗号为分隔符

        while (scanner.hasNext()) {
            System.out.println(scanner.next());
        }
        scanner.close();
    }
}

5. 实践案例

5.1 简易加法器(循环读取)

你可以使用循环不断读取输入,直到满足特定条件。

import java.util.Scanner;

public class InputLoop {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int sum = 0;
        int number;
        System.out.println("输入数字进行累加(输入 0 停止):");
        do {
            System.out.print("数值: ");
            number = scanner.nextInt();
            sum += number;
        } while (number != 0);
        System.out.println("总和为: " + sum);
        scanner.close();
    }
}

5.2 解析 CSV 行

这个例子展示了如何解析一行由逗号分隔的数据。

import java.util.Scanner;

public class CSVReader {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入 CSV 数据 (如 张三,李四,30): ");
        String csvLine = scanner.nextLine();

        // 嵌套使用 Scanner 解析这一行
        Scanner lineScanner = new Scanner(csvLine);
        lineScanner.useDelimiter(",");
        
        String firstName = lineScanner.next();
        String lastName = lineScanner.next();
        int age = Integer.parseInt(lineScanner.next()); // 转换为整数

        System.out.println("姓: " + firstName + ", 名: " + lastName + ", 年龄: " + age);
        
        lineScanner.close();
        scanner.close();
    }
}