2017-12-14 10 views
1

registerN()関数で宣言したスキャナオブジェクトを閉じ、setInfo()を使用するための新しいオブジェクトを宣言したので、エラーは発生してはなりません。しかし、私はの値として"register"を入力するたびに次の出力を得ていました。スキャナ例外エラー?

Exception in thread "main" java.util.NoSuchElementException: No line found 
    at java.util.Scanner.nextLine(Unknown Source) 
    at Student.setInfo(student.java:37) 
    at Group.registerN(student.java:87) 
    at Manage.main(student.java:168) 

これはコードで、

import java.util.*; 
import java.io.File; 
import java.io.PrintWriter; 

// **** Student details ****// 
class Student { 
    // Identity description 
    String name; 
    char sex; 
    int age; 
    String id; 
    // Educational description 
    String department; 

    void setInfo(){ 
     Scanner input = new Scanner(System.in); 

     System.out.println("Please input the following information about the student..."); 
     System.out.print("Name:\t"); 
     name = input.nextLine(); 
     System.out.print("Sex:\t"); 
     sex = Character.toLowerCase(input.next().charAt(0)); 
     System.out.print("Age:\t"); 
     age = input.nextInt(); 
     System.out.print("Department:\t"); 
     department = input.nextLine(); 
     System.out.print("ID:\t"); 
     id = input.nextLine(); 

     input.close(); 
    } 

} 
// **** **** **** **** **** **** // 


// **** Collection of the students **** // 
class Group { 
    ArrayList<Student> DB = new ArrayList<Student>(); 

    Student temp = new Student(); 

    void registerN(){ 
     Scanner input = new Scanner(System.in); 
     System.out.print("How many students would you like to register: "); 
     int n = input.nextInt(); 
     input.close(); 

     for(int i = 1; i <= n; ++i){ 
      temp.setInfo(); 
      DB.add(temp); 
      System.out.println("Student(s) " + i + " out of " + n + " registered."); 
     } 
    } 
} 
//**** **** **** **** **** **** // 

// **** A class to make use of the objects **** // 
class Manage { 

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

     Group base = new Group(); 
     // option string 
     String option = ""; 

     // I specify the options a user can input here 

     while(true){ 
      System.out.print("option: "); 
      option = input.nextLine(); 
      option = option.toLowerCase(); 

      if(option.equals("register")){ 
       base.registerN(); 
      } 
      else 
       System.out.println("\t\"" + option + "\" not recognized!\n\tReview options list."); 
     } 
     input.close(); 
    } 
} 

私はポイント制御の限界点を順番にtemp.setInfo()に制御を渡す機能base.registerN();に渡されます置きます。しかし、それが起こった直後にsetInfo()が印刷されます。私は上記のエラーを受け取ります。何故ですか?方法以下

+3

これはコードの*ロット*ですが、そのほとんどは無関係であると強く思われます。これを[mcve]に減らしてください。 –

+1

これを[mcve]に短縮することはできますか? – notyou

+0

私はそれが今より良いと確信しています –

答えて

1

あなたは()メソッドのinput.closeを呼び出す場合は、input.close();

void registerN(){ 
     Scanner input = new Scanner(System.in); 
     System.out.print("How many students would you like to register: "); 
     int n = input.nextInt(); 
     input.close(); 

を呼び出して、入力ストリームを閉じて、System.inが閉じられます。それ以上の入力は受け付けません。

あなたがこれを避けたい場合は、は、すべてのクラス

System.inで使用できるスキャナのグローバル変数を作成します。あなたのコードではなく、JVMによってインスタンス化されました。

JVMは、必要に応じて閉じます。

+1

ありがとうございます。今はうまくやっちゃダンディー! –

0

close()を呼び出してScannerを処分すると、その周囲に新しいScannerを組み込んでも、入力ストリームから読み込むことができなくなります。そのため、をregisterNの方法で閉じると、setInfoメソッド内でエラーが発生します。

あなたはむしろsetInfoメソッド内の "オンデマンド" 1を構築するよりも、あなたのコードの周りに1つのScannerオブジェクトを渡すことで、アプローチを変更する必要があります。

void setInfo(Scanner input){ 
    ... 
    name = input.nextLine(); 
    ... 
} 

またregisterNScannerを渡す:

if(option.equals("register")){ 
    base.registerN(input); 
} 

この方法でmainで作成したScannerを1つ使用し、決して閉じないでください。