質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.11%

Javaで指定された文字以外を受け付けない

解決済

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 1,116

つい先日からjavaを学び始めました。
例外処理について詰まってしまったので質問させて頂きたいです。

プログラムは標準入力で受け取った数字までのフィボナッチ数列を表示させる仕様になっています。

この標準入力の時、"exit"と"quit"が入力されるとプログラムが終了させることは出来たのですが
他の文字列が入力されしまうとエラーを吐いてしまいます。

エラー文 

Exception in thread "main" java.lang.NumberFormatException: For input string: "e"
    at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
    at java.base/java.lang.Integer.parseInt(Integer.java:652)
    at java.base/java.lang.Integer.parseInt(Integer.java:770)
    at Main.main(Main.java:11)

どのような例外処理を取れば良いのか分かりませんのでヘルプを頂きたく投稿させてもらいました。
よろしくお願い致します。

全体のコード

import java.util.Scanner;
class Main {
  public static void main(String[] args) {
    Scanner scan = new Scanner(System.in);
    while(true) {
      System.out.print("数字を入力してください(0< N <= 70) :");
      String input = scan.next();
      if (input.equals("quit") || input.equals("exit")) {
        break;
      } else {
        int num = CheckNum(Integer.parseInt(input));
        System.out.println(num + "番目のフィボナッチ数列: " + Fibonacci.calculate(num));
        System.out.println(num + "番目までのフィボナッチ数列: ");
        for(int i=1; i<=num; i++) {
          System.out.println(Fibonacci.calculate(i));
        }
      }
    }
  }
  static int CheckNum(int target) {
    while(true) {
      try {
        if (target>=1 && target<=70) return target;
      }
      catch(NumberFormatException e) {}
    } 
  }
}
class Fibonacci {
  public static long calculate(int num) {
    if(num == 1) return 0;
    if(num == 2) return 1;
    long fx = 0,
         f1 = 0,
         f2 = 1;
    for(int i=3; i<= num; i++) {
      fx = f1 + f2;
      f1 = f2;
      f2 = fx;
    }
    return fx;
  }
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

+1

問題は数値に変換できない文字列がparseInt()に突っ込まれてしまうことが原因なので、parseInt()に突っ込む前に正規表現などで数字かどうかをチェックする、または、「数字以外は異常処理」と捉えてえelseを丸々try-catchでNumberFormatException()を拾うという手もあると思います。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/08/11 23:15

    ご回答頂きありがとうございました!!

    キャンセル

+1

数値に変換できるかチェックしてから、数値に変換したいのだと思います。
だとすると、CheckNum メソッドと Integer.parseInt メソッドの呼び出しの順番が逆なのではないでしょうか?

int num = Integer.parseInt(CheckNum(input));

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/08/11 18:58

    CheckNumが引数の型をintで取ってますがこの作りだとtry-catchで拾えないのでは?

    キャンセル

  • 2019/08/11 19:21

    そうですね、CheckNumメソッドは引数もそうですが、この形に合わせて修正が必要なりますね。

    キャンセル

  • 2019/08/11 19:45

    ただ回答でのご指摘通りそもそもの処理順の間違いは認識するところからですね。

    キャンセル

  • 2019/08/11 23:14

    皆さまご丁寧にご回答頂き誠にありがとうございました!

    キャンセル

checkベストアンサー

0

いくつか気になる点があるので、プログラムを修正してみました。
できるだけ元の流れを維持するように書いたので不自然な部分もありますがご了承下さい。

変更点に関して記述します。

★1 Scannerが閉じられていない

今回は、たまたま実害は無いですが、ファイル等、閉じ忘れると痛い目に遭うことがあるので
意識だけはしておいた方がいいです。

★2 

入力された文字列が、プログラムの動作上想定されたものかどうかチェックする処理を
追加しました。
チェックして、想定通りであれば実処理をする。という流れです。
元々のCheckNumは、色々誤りがあったので使用しないようにしました。(コードご参照ください)
※ Javaのメソッド名は先頭小文字で命名することが多いです。

import java.util.Scanner;
class Main {
  public static void main(String[] args) {
    Scanner scan = new Scanner(System.in);
    while(true) {
      System.out.print("数字を入力してください(0< N <= 70) :");
      String input = scan.next();
      if (input.equals("quit") || input.equals("exit")) {
        scan.close();    // ★1
        break;
      } else {
        if (isValidNum(input)) {  // ★2
          int num = Integer.parseInt(input);  // 既にチェック済みなので問題は起きない
          System.out.println(num + "番目のフィボナッチ数列: " + Fibonacci.calculate(num));
          System.out.println(num + "番目までのフィボナッチ数列: ");
          for(int i=1; i<=num; i++) {
            System.out.println(Fibonacci.calculate(i));
          }
        }
      }
    }
  }

  static int CheckNum(int target) {
    while(true) {
      try {
        if (target>=1 && target<=70) return target;
        // バグ 範囲外の数字を入力されると無限ループします
      } catch(NumberFormatException e) {
        // バグ ここで例外は発生しません。(ここが実行されることはありません)
        // catch句を空にするのはあまり良くない書き方です
      }
    }
  }

  static boolean isValidNum(String targetStr) {
    try {
      int target = Integer.parseInt(targetStr); // 数字以外であれば例外発生
      if (target>=1 && target<=70) return true;

      System.out.println("範囲外の数字です。");
      return false;
    } catch(NumberFormatException e) {
      System.out.println("数字ではありません。");
      // e.printStackTrace();
      return false;
    }
  }
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/08/11 23:14

    丁寧にご回答頂きありがとうございます!!
    非常に分かりやすかったです。
    try&catchでの例外処理含めしっかりと理解しきれてない箇所がいくつか見つかったのでしっかりと復習しようと思います。
    ありがとうございました!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.11%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる