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

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

新規登録して質問してみよう
ただいま回答率
85.50%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

2回答

17518閲覧

Scannerを使った時に入力をしてないのにNoSuchElementExceptionが発生する

takumi00000

総合スコア11

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

1グッド

0クリップ

投稿2018/05/19 07:17

前提・実現したいこと

RPGでスライムと会敵したときに、ScannerのnextIntを使って数字でその後の行動を受け付けたい。

発生している問題・エラーメッセージ

質問のタイトルにもあるようにScanner#nextInt(書き方あってるかわからない)を使った時に入力をしていないにも関わらずNoSuchElementExceptionが発生します。

-----Enemy's Info----- Name: スライム HP: 10 Strength: 1 Vitality: 1 Dexterity: 1 Agility: 1 ---------------------- 0. 攻撃 1. 防御 2. 道具 3. 逃げる Exception in thread "main" java.util.NoSuchElementException at java.util.Scanner.throwFor(Scanner.java:862) at java.util.Scanner.next(Scanner.java:1485) at java.util.Scanner.nextInt(Scanner.java:2117) at java.util.Scanner.nextInt(Scanner.java:2076) at player.EnemyCount.count(EnemyCount.java:26) at hajimari.Spawn.first(Spawn.java:11) at core.RPGCore.main(RPGCore.java:14)

該当のソースコード

EnemyCount.java

package player; import java.util.Scanner; import entities.Slime; import entity.Attack; import entity.Defence; import entity.Escape; import entity.Inventory; public class EnemyCount { public static void count(String name) { System.out.println("-----Enemy's Info-----"); Slime.getInfo(); System.out.println("----------------------"); System.out.println("0. 攻撃"); System.out.println("1. 防御"); System.out.println("2. 道具"); System.out.println("3. 逃げる"); Scanner sc = null; try{ sc = new Scanner(System.in); int data = sc.nextInt(); switch(data){ case 0: Attack.player(); break; case 1: Defence.player(); break; case 2: Inventory.player(); break; case 3: Escape.player(); break; default: System.out.println("デバッグ: events.player.EnemyCountで不正な入力"); break; } } catch(NullPointerException e){ System.out.println("デバッグ: Error at events.player.EnemyCount(" + e + ")"); } finally { if(sc != null) sc.close(); } System.out.println("end"); } }

Slime.java

package entities; public class Slime { public static String Name = "スライム"; static int HP = 10; static int Strength = 1; static int Vitality = 1; static int Dexterity = 1; static int Agility = 1; public static void getInfo(){ System.out.println("Name: " + Name); System.out.println("HP: " + HP); System.out.println("Strength: " + Strength); System.out.println("Vitality: " + Vitality); System.out.println("Dexterity: " + Dexterity); System.out.println("Agility: " + Agility); } }

Attack.player()などの○○.player()は、
Attack.player()であればSystem.out.println("attacked");を実行するだけです.

試したこと

NoSuchElementExceptionが何故出るのかと思い、Googleで検索してみましたが、解決方法を見つけることはできませんでした。

補足情報

Eclipse4.6 Neon日本語版を使用しています。
初心者中の初心者ですので、私の質問で不足しているところがあればご指摘のほどよろしくお願いします。

DrqYuto👍を押しています

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/05/19 07:55

count()を呼ぶ前にScannerもしくはSystem.inを閉じていませんか?
guest

回答2

0

ベストアンサー

おそらく「Scannerの使い方が不適切」です。

countメソッドは何度も呼び出されるメソッドだと思います。その中で毎回Scannerインスタンスをnewしてメソッドが終わるときにcloseしていますね?closeするとSystem.inもcloseされます。よって2回目にこのメソッドを呼び出したときには既にSystem.inはclose済みなので二度と入力処理はできません。

そのためNoSuchElementExceptionが発生したのでしょう。

対策:

プログラムの中ではScannerは一度だけ生成し、それをずっと使い続けてください。closeをする適切なタイミングはアプリケーションを終了するときです。

countメソッドの中でScannerインスタンスが必要なのでcountメソッドの引数として渡すかフィールドに覚えておくかしなければなりません。


追記:
staticメソッドを極力使わず、各クラスの各メソッドの引数に一々Scannerなどの情報を渡さずに済ます骨組みみたいなものを書いてみました。(単なる一例です)

java

1class RPG { 2 public static void main(String[] args) { 3 try (sc = new Scanner(System.in)) { 4 RPG rpg = new RPG(); 5 rpg.sc = sc; 6 rpg.run(); 7 } 8 } 9 10 Scanner sc; 11 Hero hero; 12 13 void run() { 14 hero = new Hero(this, "勇者サトゥー"); 15 for (;;) { 16 ... 17 // スライム出たー 18 encounter(); 19 hero.encounter(); 20 } 21 } 22 23 static void encounter() { 24 int decision = sc.nextInt(); // こうすればScannerにアクセスできる 25 ... 26 } 27} 28 29class Hero { 30 RPG rpg; 31 String name; 32 33 Hero(RPG rpg, String name) { 34 this.rpg = rpg; 35 this.name = name; 36 } 37 38 void encounter() { 39 int decision = rpg.sc.nextInt(); // こうすればScannerにアクセスできる 40 } 41}

必要なインスタンス(RPGインスタンスやHeroインスタンス)の繋がりをフィールドに覚えておくとそのフィールドを通じて必要なインスタンスの必要な情報に全て手が伸ばせるという感じです。

投稿2018/05/19 07:55

編集2018/05/19 09:24
KSwordOfHaste

総合スコア18392

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

takumi00000

2018/05/19 09:07

KSwordOFHasteさん、回答ありがとうございます。 あなたのおかげで、解決することができました。ですが、対策に書かれた、「フィールドに覚えておく」というものの、やり方がわかりません。良ければ教えていただけると幸いです。
takumi00000

2018/05/20 09:28

追記いただきありがとうございます。おかげで今回の原因と対策を理解することが出来ました。 よって、KSwordOfHasteさんをベストアンサーとさせていただきます。 *他の方々も、回答ありがとうございます。*
退会済みユーザー

退会済みユーザー

2018/05/20 10:10

どこのデスマーチですかw
KSwordOfHaste

2018/05/20 10:27

失礼しました。3日風呂に入れないのくだりが印象に残ってたのでつい...
guest

0

こんにちは

原因は最初のScanner sc = null;だと思われます。最初の宣言でScanner sc = new Scanner(System.in);にしてみてください。

これによりtry ~ catchのところをInputMismatchException eが不要となり、
その代わりにInputMismatchException eを付けました。
(数字以外が入力されたとき出るエラーです。)

Java

1public class Main { 2 public static void main(String[] args) { 3 4 System.out.println("-----Enemy's Info-----"); 5 System.out.println("----------------------"); 6 System.out.println("0. 攻撃"); 7 System.out.println("1. 防御"); 8 System.out.println("2. 道具"); 9 System.out.println("3. 逃げる"); 10 11     Scanner sc = new Scanner(System.in); 12 try{ 13 int data = sc.nextInt(); 14 switch(data){ 15 case 0: 16 System.out.println("攻撃"); 17 break; 18 case 1: 19 System.out.println("防御"); 20 break; 21 case 2: 22 System.out.println("道具"); 23 break; 24 case 3: 25 System.out.println("逃げる"); 26 break; 27 default: 28 System.out.println("デバッグ: events.player.EnemyCountで不正な入力"); 29 break; 30 } 31 } 32 catch(InputMismatchException e){ 33 System.out.println("数字を入力してください。"); 34 } 35 36 System.out.println("end"); 37 } 38 39}

投稿2018/05/19 07:31

編集2018/05/19 07:43
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

takumi00000

2018/05/19 07:38

回答ありがとうございます。 実行してみましたが、質問と同じエラーが帰ってきます。
LouiS0616

2018/05/19 07:41 編集

@Stars1024 さん 元のコードでもtryブロック内でしっかりScannerインスタンスを生成しているように見えるのですが。
退会済みユーザー

退会済みユーザー

2018/05/19 07:52

Scannerをtry~catchの外に出しました。私が使っている環境ではScannerがtry~catchの中にあっても 外にあってもエラーが出なかったのですが、環境によってはエラーが出るんですね。 すみません。
LouiS0616

2018/05/19 07:54

Scannerの未初期化に起因するエラーなら、NoSuch... とか InputMismatch... より先にヌルポが出るはずです。だって参照解決できませんから。
退会済みユーザー

退会済みユーザー

2018/05/19 16:43

なんか話の流れからGUIアプリ(アプレットかもしれないが)でやってる感じだよな
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問