当前位置: 动力学知识库 > 问答 > 编程问答 >

java.util.scanner - java - Scanner class NoSuchElementFoundException

问题描述:

This question already has an answer here:

  • NoSuchElementException with Java.Util.Scanner

    4 answers

网友答案:

Never catch an exception unless you are going to do something useful with it.

I got it to work. It was fairly straight forward.

Enter path to save your file : myfile.bin
Enter Employee ID : 99
Enter Employee Name : Rick Hightower
Enter Employee Salary : 99
Add more records [true/false]? true
Enter Employee ID : 77
Enter Employee Name : Dippy Do
Enter Employee Salary : 88
Add more records [true/false]? false

Here is what I have: ...

public static class Employee implements  Serializable {

    int id;
    String name;
    int salary;

    public Employee(int id, String name, int salary) {
        this.id = id;
        this.name = name;
        this.salary = salary;
    }

}

static Employee getData() throws IOException {
    BufferedReader rdr = new BufferedReader(
            new InputStreamReader(
                    new DataInputStream(System.in)
            ));
    System.out.printf("Enter Employee ID : ");
    int tmpid = Integer.parseInt(rdr.readLine());
    System.out.printf("Enter Employee Name : ");
    String tmpname = rdr.readLine();
    System.out.printf("Enter Employee Salary : ");
    int tmpsalary = Integer.parseInt(rdr.readLine());
    //rdr.close(); this is why... you broke it :)
    return new Employee(tmpid, tmpname, tmpsalary);
}

public static void main(String []args) throws Exception {
    boolean moreRecords = true;
    String path = null;
    Scanner scanner = new Scanner(System.in);
    File file = null;
    System.out.printf("Enter path to save your file : ");
    path = scanner.next();
    file = new File(path);


    while (moreRecords) {
        Employee rec = Main.getData();
        ObjectOutputStream dos = new ObjectOutputStream(new FileOutputStream(file));
        dos.writeObject(rec);
        dos.close();
        System.out.printf("Add more records [true/false]? ");
        moreRecords = scanner.nextBoolean();
    }

It is mostly your code with some parts taken away.

The biggest issue you had was you were closing the input stream.

static Employee getData() throws IOException {
    BufferedReader rdr = new BufferedReader(
            new InputStreamReader(
                    new DataInputStream(System.in)
            ));
    System.out.printf("Enter Employee ID : ");
    int tmpid = Integer.parseInt(rdr.readLine());
    System.out.printf("Enter Employee Name : ");
    String tmpname = rdr.readLine();
    System.out.printf("Enter Employee Salary : ");
    int tmpsalary = Integer.parseInt(rdr.readLine());
    //rdr.close(); this is why... you broke it :)       <-------------------SEE
    return new Employee(tmpid, tmpname, tmpsalary);
}

The Java I/O stream uses the decorator pattern so it just keeps delegating the close call into the inner streams.

That fixes that problem. There are lots of problems with your code.

If you are using JDK 1.7 or later, it will close the file for you.

    while (moreRecords) {
        Employee rec = Main.getData();

        try ( ObjectOutputStream dos =
                     new ObjectOutputStream(
                             new FileOutputStream(file) ) ) {

            dos.writeObject(rec);

        }

        System.out.printf("Add more records [true/false]? ");
        moreRecords = scanner.nextBoolean();
    }

If you are using JDK 1.6 or JDK 1.5:

    while (moreRecords) {
        Employee rec = Main.getData();

        ObjectOutputStream dos = null;
        try {
            dos = new ObjectOutputStream(
                            new FileOutputStream(file) );
            dos.writeObject(rec);

        } finally {
           if ( dos!=null  ) {
                dos.close();
           }
        }

        System.out.printf("Add more records [true/false]? ");
        moreRecords = scanner.nextBoolean();
    }

Also, your program should do more validation of user input. Scanner can do that as follows:

public static class Employee implements  Serializable {

    private int id;
    private String name;
    private BigDecimal salary;

    public Employee(int id, String name, BigDecimal salary) {
        this.id = id;
        this.name = name;
        this.salary = salary;
    }

}

static Employee getData(Scanner scanner) throws IOException {

    System.out.printf("Enter Employee ID : ");
    while ( !scanner.hasNextInt() ) {
        System.out.println("Employee IDs are numbers only");
        scanner.next();
    }

    int employeeId = scanner.nextInt();

    System.out.printf("Enter Employee Name : ");
    String name = scanner.next();


    System.out.printf("Enter Employee Salary : ");

    while ( !scanner.hasNextBigDecimal() ) {
        System.out.println("Employee salaries are decimals " +
                "not random gak");
        scanner.next();
    }
    BigDecimal salary = scanner.nextBigDecimal();

    return new Employee(employeeId, name, salary);
}


public static void main(String []args) throws Exception {
    boolean moreRecords = true;
    String path = null;
    Scanner scanner = new Scanner(System.in);
    File file = null;
    System.out.printf("Enter path to save your file : ");
    path = scanner.next();
    file = new File(path);


    while (moreRecords) {
        Employee rec = Main.getData(scanner);

        try ( ObjectOutputStream dos =
                      new ObjectOutputStream(
                            new FileOutputStream(file) ) ) {
            dos.writeObject(rec);

        }

        System.out.printf("Add more records [true/false]? ");
        moreRecords = scanner.nextBoolean();

Now the input/output is more like this:

Enter path to save your file : asdfasdf
Enter Employee ID : 9a
Employee IDs are numbers only
99
Enter Employee Name : Rick
Enter Employee Salary : aa
Employee salaries are decimals not random gak
99.99
Add more records [true/false]? false

The scanner forces the end user to enter in the right types of data. You can combine it with regex to match patterns for names, etc.

I extended the example and added some discussion of the Scanner.

http://rick-hightower.blogspot.com/2013/10/java-scanner-example.html

网友答案:

In nextInt(), NoSuchElementFoundException occurs when the input is exhausted. So check the input that you give at prompt.

分享给朋友:
您可能感兴趣的文章:
随机阅读: