尝试从文本文件中读取双精度值,但抛出 InputMismatchException

Attempting to read double values from a textfile, but a InputMismatchException is thrown

我正在尝试制作一个处理 "large" 文本文件的程序。文本文件显示 1000 行,每行代表一名教职员工。每行包含名字、姓氏、等级和薪水。

Link 到文本文件: http://cs.armstrong.edu/liang/data/Salary.txt

程序应该按职级统计雇员人数,以及每组的总工资。最后,应显示每个组的总薪水,以及给定级别的员工的平均薪水。我还没有完成整个程序,我目前正在确保正确读取文本文件。

下面的代码示例:

package ch12;
import java.util.Scanner;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

public class Chapter_12_E25_ProcessLargeDataSet {

    public static void main(String[] args) throws IOException {

        int assistantCount = 0;
        int associateCount = 0;
        int fullCount = 0;
        int facultyCount = 0;

        double assistantSalary = 0;
        double associateSalary = 0;
        double fullSalary = 0;
        double facultySalary = 0;

        try {
            URL url = new URL("http://cs.armstrong.edu/liang/data/Salary.txt");
            Scanner input = new Scanner(url.openStream());

            while (input.hasNext()) {

                String firstName = input.next();
                String lastName = input.next();
                String rank = input.next();
                double salary = input.nextDouble();

                if (rank.contains("assistant")) {
                    assistantCount++;
                    System.out.println("Rank is " + rank + " and salary is " + salary);

                } else if (rank.contains("associate")) {
                    associateCount++;
                    System.out.println("Rank is " + rank + " and salary is " + salary);
                } else {
                    fullCount++;
                    System.out.println("Rank is " + rank + " and salary is " + salary);
                }   
            }
            input.close();
        }
        catch (MalformedURLException ex) {
            ex.printStackTrace();
            System.exit(1);
        }
        catch (FileNotFoundException ex) {
            ex.printStackTrace();
            System.exit(2);
        }

    }

}

double salary = input.nextDouble() 导致 InputMismatchException 。如果我将变量 salary 更改为 String 而不是 double,则会正确读取薪水。如果我将 double salary = input.nextDouble() 更改为 double salary = Double.parseDouble(input.next()),我将得到正确的 double 值。使用这种方法并不困扰我,但我很好奇为什么 scanner 不接受工资作为 double 值。

谁能解释一下为什么?

另外,一个题外话的子题。如果我将 URL object 参数中的文件名 Salary.txt 更改为不存在的文件,则不会抛出 catch statement nr2 中的 FileNotFoundException,而是 InputMismatchException 被抛出。为什么抛出 InputMismatchException 而不是 FileNotFoundException

虽然我不熟悉扫描仪,但快速浏览 api 发现了多种 "hasNext(something)" 方法。比如...

hasNextInt()

hasNextFloat()

hasNextDouble()

有下一行()

现在您可能希望程序弄清楚接下来应该使用什么。如果您正确设置程序,我认为您可以简单地用 "hasNext(something)" 测试下一行的每种可能的值类型。当 hasNext(something) returns 为 true 时,则获取带有 next(something) 的值。 示例中的概念是...

hasNextInt() returns 错误...

(跳过 nextInt() )

hasNextDouble() returns 真...

nextDouble()

你需要看看https://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html

很可能您的扫描仪使用了错误的语言环境。根据您 Salary.txt 的值,您只需将扫描仪的区域设置更改为英语即可。试试这个:

import java.util.Locale;
...
Scanner input = new Scanner(url.openStream());
input.useLocale(Locale.ENGLISH);

Also, a sub question that is off-topic. If I change the filename Salary.txt in the argument for the URL object to a file that does not exists, FileNotFoundException in catch statement nr2 is not thrown, but instead an InputMismatchException is thrown. Why is the InputMismatchException thrown instead of FileNotFoundException?

服务器实际传送的文件(很可能是 404)与打开流的预期格式不匹配。

The line double salary = input.nextDouble() causes an InputMismatchException . If i change the variable salary to a String instead of a double, the salary is read correctly. If i change double salary = input.nextDouble() into double salary = Double.parseDouble(input.next()), I get the right double value. It doesen't bother me to use this approach, but I'm just curious why the scanner does not accept the salaries as a double value.

您的整个程序非常脆弱,如果文件格式没有 100% 正确保存,将会崩溃(或者更糟:delvier 错误结果)。我建议阅读整行,然后使用正则表达式拆分。然后检查所有值是否都是预期类型(例如 double/String)而不是 null,然后继续将它们添加到您的统计信息中。如果拆分 fails/values 是 null/wrong,您可以在输出中添加一条错误消息并跳过该行继续。