Java | 基礎文法:Scanner 入力

Java Java
スポンサーリンク

Scanner 入力の全体像

Scanner は「テキストをトークン(単語・数値など)に分解して読み取る」ためのユーティリティです。標準入力(キーボード)だけでなく、文字列、ファイル、入力ストリームからも扱えます。最大の利点は「型別の読み取りメソッド(nextInt, nextDouble, nextLine など)」と「入力の有無を確認するメソッド(hasNextXXX)」を備えていて、初心者でも安全に使えることです。


基本の使い方と標準入力

標準入力から読み取る(最小例)

import java.util.Scanner;

public class ReadBasic {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in); // キーボード入力
        System.out.print("年齢を入力: ");
        int age = sc.nextInt();               // 数値トークンを取得
        sc.nextLine();                        // 改行を消費(後述の罠対策)
        System.out.print("名前を入力: ");
        String name = sc.nextLine();          // 1行まるごと取得
        System.out.println("こんにちは " + name + "(" + age + "歳)");
        sc.close();                            // 明示的に閉じる(または try-with-resources)
    }
}
Java
  • nextInt/nextDouble: 空白や改行で区切られた「数値トークン」を読みます。
  • nextLine: 改行まで「1行全体」を読みます。
  • close: 使い終わったら閉じるのが基本です。標準入力を閉じると再利用できないため、短いプログラムなら最後に閉じるか、明示的に閉じない選択も現実的です。

重要ポイントの深掘り:トークンと行の違い、nextLine の罠

トークン読み取りと行読み取りの違い

  • トークン系(nextInt, next, nextDouble): 空白や改行で区切られた「次の単語」を返します。区切りは既定で空白類(スペース、タブ、改行)。
  • 行系(nextLine): 改行までの「その行の残りすべて」を返します。空白も含みます。

この違いを意識して組み合わせることが重要です。

nextInt の後に nextLine が空振りする問題

nextInt() は数値だけを取り、行末の改行は残したままにします。続けて nextLine() を呼ぶと、その残った改行だけを読み取り「空文字」を返す、という事故がよく起きます。

int age = sc.nextInt();
String name = sc.nextLine(); // ← 直前の改行を読んでしまい、空文字になる
Java

対策は「トークン系の後に行系を使う前に、改行を1回捨てる」ことです。

int age = sc.nextInt();
sc.nextLine();            // 改行のクリア
String name = sc.nextLine();
Java

または「常に行で受けてから、パースする」方式にすると安全です。

int age = Integer.parseInt(sc.nextLine().trim());
Java

入力検証と安全な読み取り

hasNextXXX で存在確認

System.out.print("整数を入力: ");
if (sc.hasNextInt()) {
    int n = sc.nextInt();
    System.out.println("OK: " + n);
} else {
    System.out.println("整数ではありません");
    sc.nextLine(); // 誤入力の行を捨てる
}
Java
  • hasNextInt/hasNextDouble: 次トークンが指定型として読み取れるかを事前確認。
  • hasNextLine: 次の行が存在するか。

例外を避ける安全入力ユーティリティ

static int readIntSafely(Scanner sc, String prompt) {
    while (true) {
        System.out.print(prompt);
        if (sc.hasNextInt()) {
            int v = sc.nextInt();
            sc.nextLine(); // 改行クリア
            return v;
        } else {
            System.out.println("整数を入力してください。");
            sc.nextLine(); // 誤入力を破棄
        }
    }
}
Java

「存在確認 → 誤入力を破棄 → 再入力」をひとまとめにすると、対話入力が安定します。


デリミタ、ロケール、文字コード(実務で効く設定)

区切り文字(デリミタ)の変更

Scanner sc = new Scanner("10,20,30");
sc.useDelimiter(","); // カンマ区切りに変更
while (sc.hasNextInt()) {
    System.out.println(sc.nextInt()); // 10 20 30
}
sc.close();
Java

CSV の一部処理や特殊な区切りに便利です。複雑な CSV は専用ライブラリを検討しましょう。

ロケールで小数点や数字書式を合わせる

Scanner sc = new Scanner("3,14");
sc.useLocale(java.util.Locale.GERMANY); // ドイツでは小数点が「,」
System.out.println(sc.nextDouble());    // 3.14
Java

小数点記号が国によって違う場合は useLocale で整合を取ります。

文字コード(ファイル・ストリーム入力)

import java.nio.charset.StandardCharsets;
import java.io.File;
import java.util.Scanner;

try (Scanner sc = new Scanner(new File("data.txt"), StandardCharsets.UTF_8)) {
    while (sc.hasNextLine()) System.out.println(sc.nextLine());
}
Java

日本語テキストなどは文字コードを明示すると文字化けを防げます。


リソース管理とファイル入力

try-with-resources で安全に閉じる

import java.util.Scanner;
import java.io.File;

public class ReadFile {
    public static void main(String[] args) throws Exception {
        try (Scanner sc = new Scanner(new File("input.txt"))) {
            while (sc.hasNextLine()) {
                String line = sc.nextLine();
                System.out.println("read: " + line);
            }
        } // 自動で close
    }
}
Java
  • ファイル/ネットワーク入力: 必ず try-with-resources を使う。例外時でも確実に閉じられます。
  • 標準入力: アプリの最後で閉じるか、短命プログラムなら未 close でも実害は少ないです(ただしライブラリや長寿命プロセスでは明示的に管理)。

例題で身につける

例 1: 1行ずつ読み、空行で終了

import java.util.Scanner;

public class UntilBlank {
    public static void main(String[] args) {
        try (Scanner sc = new Scanner(System.in)) {
            System.out.println("空行で終了。入力してください:");
            while (true) {
                String line = sc.nextLine();
                if (line.isBlank()) break;
                System.out.println("echo: " + line.trim());
            }
        }
    }
}
Java

例 2: 整数リストを読み、合計を出す(安全版)

import java.util.Scanner;

public class SumInts {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int sum = 0;
        System.out.println("整数をスペース区切りで入力(非整数は無視、改行で終了):");
        while (sc.hasNext()) {
            if (sc.hasNextInt()) sum += sc.nextInt();
            else sc.next(); // 非整数トークンを捨てる
        }
        System.out.println("sum=" + sum);
        sc.close();
    }
}
Java

例 3: 行で受けてからパース(nextLine 方式)

import java.util.Scanner;

public class ParseLine {
    public static void main(String[] args) {
        try (Scanner sc = new Scanner(System.in)) {
            System.out.print("価格を入力(整数): ");
            int price = Integer.parseInt(sc.nextLine().trim());
            System.out.print("税率を入力(例 0.1): ");
            double tax = Double.parseDouble(sc.nextLine().trim());
            System.out.println("税込=" + Math.round(price * (1 + tax)));
        }
    }
}
Java

仕上げのアドバイス(重要部分のまとめ)

  • トークン系(nextInt/next)と行系(nextLine)の違いを理解し、混在時は「改行クリア」か「行→パース」に統一する。
  • hasNextXXX で入力検証し、誤入力は破棄して再入力を促す。例外を前提にしない設計が初心者にも安全。
  • 区切り(useDelimiter)、ロケール(useLocale)、文字コード(コンストラクタの charset)を明示すると、国際化やファイル入力で安定する。
  • リソースは try-with-resources で確実に閉じる。標準入力は最後に閉じるか、短命なら無理に閉じない。
  • 大量データや高速処理が必要なら BufferedReader+手動パースも検討し、Scanner は「簡単で安全」を優先する場面で使う。

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