【问题标题】:How can I take a String with a name and two values and separate it into a String containing the name and 2 doubles containing the values?如何获取具有名称和两个值的字符串并将其分隔为包含名称的字符串和包含值的 2 个双精度值?
【发布时间】:2021-09-06 09:28:00
【问题描述】:

我为一个旨在帮助管理排球队名册的程序编写了一个类。名单包含在一个 .dat 文件中,球员的写法如下:

Rachael Adams 3.36 1.93

当我尝试将此字符串分隔为适当的数据类型(名称是字符串,然后第一个和第二个值是统计数据的两倍)时,我的问题就出现了。

public Roster(String filename) {
    players = new ArrayList<Player>();
    
    try {
        FileReader fr = new FileReader(filename);
        BufferedReader inFile = new BufferedReader (fr);
        
        String line = inFile.readLine();
        Scanner scan = new Scanner(line);
        
        while(line != null) {
            String firstName = scan.next();
            String lastName = scan.next();
            double attackStat = scan.nextDouble();
            double blockStat = scan.nextDouble();
            String name = firstName + " " + lastName;
            Player newPlayer = new Player(name, attackStat, blockStat);
            players.add(newPlayer);
            line = inFile.readLine();
        }
        scan.close();
        inFile.close();
        
    } catch (IOException e) {
        System.out.println(e);
    }
}

程序在创建名册对象时抛出此异常

Exception in thread "main" java.util.InputMismatchException
        at java.base/java.util.Scanner.throwFor(Scanner.java:939)
        at java.base/java.util.Scanner.next(Scanner.java:1594)
        at java.base/java.util.Scanner.nextDouble(Scanner.java:2564)
        at Roster.<init>(Roster.java:30)
        at Assignment08.openRosterFile(Assignment08.java:59)
        at Assignment08.main(Assignment08.java:18)

我是 Java 新手,仍然面临学习曲线,所以如果需要更多信息,请告诉我。

如果可能的话,我将不胜感激解释我做错了什么,而不仅仅是一个解决方案。非常感谢。

【问题讨论】:

  • 您是否尝试过两次 Scanner.next() 以分别获取名字和姓氏?我说的是 2 .next() 然后是 2 nextDouble() 如果数据格式是用给定的例子固定的
  • 为什么nextDouble() 会在行首工作?此外,当您阅读下一篇 line 时,您并没有更新它。
  • @shmosel 我不确定我是否理解您在阅读下一个line 时不更新它的意思。我的理解是,在while 循环结束时,它会读取下一行并更新line,然后循环回到开头并再次遍历它们。如果这种理解不正确或者您指的是其他内容,请告诉我。我确实看到nextDouble() 不会像我那样工作。谢谢
  • @shmosel 正确观察到了什么,为什么您认为 Scanner scan... 不在 while 循环中?当您到达第二次迭代时,line 的值在 scan 变量中是多少?
  • @Jimmy 谢谢。我没有意识到 scan 变量中的值不会更新。它现在可以正常工作了

标签: java class exception io


【解决方案1】:

我总是觉得分割线更容易:

String[] columns = line.split(" (?=\\d)";
String name = columns[0];
double attackStat = Double.parseDouble(columns[1]);
double blockStat =  Double.parseDouble(columns[2]);

这通过在空格上拆分来工作,但仅当下一个字符是通过 look ahead (?=\d) 的数字时。

这会自动满足名称中任意数量的单词。

【讨论】:

  • 谢谢!这样做更有意义,以考虑名称中可能有额外空格的玩家。
  • 是的。关键是您将 parsing 行与 reading 从磁盘中的行分开。如果您过多使用 Scanner 的 API,就会将 IO 与解析结合起来,这会使您的实现难以维护、调试和测试。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-19
  • 1970-01-01
  • 2019-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多