【プログラミングしてみよう33】JavaのScannerを深める(入力バリデーション)

Java

前回は標準ライブラリだけでJSONを扱う方法を学びました。

今回は「入力バリデーション」について解説します。 Scannerを使った入力受け取りはシリーズ序盤に学びましたが、実際のアプリでは「数字を入力してほしいのに文字を入れられた」「範囲外の値を入力された」といった場面に対応する必要があります。これまで学んだ例外処理・正規表現・ループを組み合わせて、より堅牢な入力処理を作りましょう。

入力バリデーションの基本

ユーザーからの入力はいつも正しいとは限りません。たとえば nextInt() を使って整数を受け取ろうとしているときに文字列が入力されると、InputMismatchException が発生してプログラムが止まってしまいます。

Scanner sc = new Scanner(System.in);
int number = sc.nextInt(); // "abc"と入力するとエラー

入力バリデーションとは、受け取った値が正しい形式・範囲に収まっているかを確認し、問題があれば再入力を促す処理のことです。ループと例外処理を組み合わせることで、正しい値が入力されるまで繰り返し入力を求めることができます。

サンプルコード(数値の入力バリデーション)

ファイル作成

「Java22」フォルダに InputValidTest.java という名前でファイルを作成します

コード入力

以下のコードを入力します。

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

public class InputValidTest {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int number = 0;
        boolean isValid = false;

        while (!isValid) {
            System.out.print("1から100の整数を入力してください: ");
            try {
                number = sc.nextInt();
                if (number >= 1 && number <= 100) {
                    isValid = true;
                } else {
                    System.out.println("エラー: 1から100の範囲で入力してください");
                }
            } catch (InputMismatchException e) {
                System.out.println("エラー: 整数を入力してください");
                sc.nextLine(); // 不正な入力をバッファから取り除く
            }
        }

        System.out.println("入力された値: " + number);
        sc.close();
    }
}

コンパイル

javac InputValidTest.java

実行

java InputValidTest

次のように入力してみます。

1から100の整数を入力してください: abc
エラー: 整数を入力してください
1から100の整数を入力してください: 200
エラー: 1から100の範囲で入力してください
1から100の整数を入力してください: 42

実行結果は次のようになります。

入力された値: 42

サンプルコード(複数条件のバリデーション)

ファイル作成

「Java22」フォルダに MultiValidTest.java という名前でファイルを作成します

コード入力

以下のコードを入力します。

import java.util.Scanner;

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

        // 名前の入力バリデーション(空文字・長すぎる入力を弾く)
        String name = "";
        while (true) {
            System.out.print("名前を入力してください(1〜10文字): ");
            name = sc.nextLine().trim();
            if (name.isEmpty()) {
                System.out.println("エラー: 名前を入力してください");
            } else if (name.length() > 10) {
                System.out.println("エラー: 10文字以内で入力してください");
            } else {
                break;
            }
        }

        // メールアドレスの入力バリデーション(正規表現で形式チェック)
        String email = "";
        String emailPattern = "^[\\w.+-]+@[\\w-]+\\.[a-zA-Z]{2,}$";
        while (true) {
            System.out.print("メールアドレスを入力してください: ");
            email = sc.nextLine().trim();
            if (email.matches(emailPattern)) {
                break;
            } else {
                System.out.println("エラー: 正しいメールアドレスの形式で入力してください");
            }
        }

        // 年齢の入力バリデーション
        int age = 0;
        while (true) {
            System.out.print("年齢を入力してください(0〜120): ");
            String input = sc.nextLine().trim();
            try {
                age = Integer.parseInt(input);
                if (age >= 0 && age <= 120) {
                    break;
                } else {
                    System.out.println("エラー: 0から120の範囲で入力してください");
                }
            } catch (NumberFormatException e) {
                System.out.println("エラー: 整数を入力してください");
            }
        }

        System.out.println("\n--- 入力内容の確認 ---");
        System.out.println("名前: " + name);
        System.out.println("メール: " + email);
        System.out.println("年齢: " + age);

        sc.close();
    }
}

コンパイル

javac MultiValidTest.java

実行

java MultiValidTest

次のように入力してみます。

名前を入力してください(1〜10文字): 
エラー: 名前を入力してください
名前を入力してください(1〜10文字): ぱんまる
メールアドレスを入力してください: panmaru
エラー: 正しいメールアドレスの形式で入力してください
メールアドレスを入力してください: panmaru@example.com
年齢を入力してください(0〜120): abc
エラー: 整数を入力してください
年齢を入力してください(0〜120): 25

実行結果は次のようになります。

--- 入力内容の確認 ---
名前: ぱんまる
メール: panmaru@example.com
年齢: 25

コードの解説

1つ目のサンプルでは、while (!isValid) ループの中でtry-catchを使い、InputMismatchException が発生した場合はエラーを表示して再度ループします。sc.nextLine() をcatchブロックで呼んでいるのは、不正な入力がScannerのバッファに残ったままになるため、それを取り除くためです。これを忘れると同じエラーが無限に繰り返されてしまいます。

2つ目のサンプルでは、while (true)break を組み合わせて「条件を満たしたらループを抜ける」パターンを使っています。nextLine() で1行まるごと文字列として受け取り、Integer.parseInt() で整数に変換することで、InputMismatchException ではなく NumberFormatException をキャッチしています。この方法は nextInt() よりも柔軟で、バッファの問題も起きにくいため、実際の開発でよく使われます。

メールアドレスの検証には以前学んだ正規表現を活用しています。matches() で形式チェックし、正しい形式が入力されるまでループを続けます。このようにこれまで学んだ技術を組み合わせることで、実用的な入力処理が作れます。

まとめ

入力バリデーションは、ユーザーからの不正な入力に対してプログラムを止めずに適切に対処するための重要な技術です。while ループと try-catch を組み合わせて「正しい値が入力されるまで繰り返す」パターンを覚えておきましょう。nextInt() を使う場合はバッファのクリアを忘れずに、nextLine() で受け取って Integer.parseInt() で変換する方法も実践的です。正規表現との組み合わせで、メールアドレスや郵便番号など形式チェックも柔軟に行えます。

2026/07/12(日) ぱんまる

コメント

タイトルとURLをコピーしました