【问题标题】:Parsing through a file that uses whitespace as a delimiter -java. (I dont understsand it)解析使用空格作为分隔符的文件 -java。 (我不明白)
【发布时间】:2017-04-02 22:16:12
【问题描述】:

有人可以帮我理解我做错了什么吗? 我必须通读每行包含 11 个整数和双精度数的文件,每行都需要成为自己的对象并存储在 arrayList 中。但是,分隔符是一个空格。我已经使用了这段代码,但它似乎不起作用,我不确定我做错了什么。

package p2_0000000;

import java.util.Scanner;
import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;


public class P2_000000 {


    public static void main(String[] args) {
        // TODO code application logic here
        System.out.println("Which file year would you like to analyze:\n"
                + "1) 2007\n"
                + "2) 2011\n"
                + "3) 2013\n"
                + "(Enter number for choice)");
        Scanner input = new Scanner(System.in);
        int choice = input.nextInt();
        ArrayList<dwellingClass> alist = new ArrayList<dwellingClass>();
        if (choice == 1) {
            try {
                File file = new File("2007.txt");
                Scanner scanner = new Scanner(file);


                while (scanner.hasNextLine()) {
                    String line = scanner.nextLine();
                    String[] info = line.split(" ");

                    int age = Integer.parseInt(info[0]);
                    int region = Integer.parseInt(info[1]);
                    double lmed = Double.parseDouble(info[2]);
                    double fmr = Double.parseDouble(info[3]);
                    double extremelyLowIncome = Double.parseDouble(info[4]);
                    double veryLowIncome = Double.parseDouble(info[5]);
                    double lowIncome = Double.parseDouble(info[6]);
                    int bedrooms = Integer.parseInt(info[7]);
                    double value = Double.parseDouble(info[8]);
                    int rooms = Integer.parseInt(info[9]);
                    double utility = Double.parseDouble(info[10]);

                    dwellingClass dwelling = new dwellingClass(age, region, lmed, fmr, extremelyLowIncome, veryLowIncome, lowIncome, bedrooms, value, rooms, utility);
                    alist.add(dwelling);

                }
                scanner.close();

            } catch (Exception a) {
                a.printStackTrace();
                System.exit(0);
            };
            for (dwellingClass each : alist) {
                System.out.println(each);
            }

        }

        System.out.println(alist.get(0).getAge());
    }
}

我收到以下错误:

java.lang.NumberFormatException: For input string: ""
    at        java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
    at java.lang.Integer.parseInt(Integer.java:592)
    at java.lang.Integer.parseInt(Integer.java:615)

感谢大家的帮助! 我还发现这也适用于以后阅读这篇文章的任何人:

public class P2_0000000 {

    public static void main(String[] args) {
        // TODO code application logic here
        ArrayList<dwellingClass> alist = new ArrayList<dwellingClass>();
        try {
            File file = new File("2007.txt");
            Scanner input = new Scanner(file);

            while (input.hasNext()) {

                int age = input.nextInt();
                int region = input.nextInt();
                double lmed = input.nextDouble();
                double fmr = input.nextDouble(); 
                double extremelyLowIncome = input.nextDouble();
                double veryLowIncome = input.nextDouble();
                double lowIncome = input.nextDouble();
                int bedrooms = input.nextInt();
                double value = input.nextDouble();
                int rooms = input.nextInt(); 
                double utility = input.nextDouble(); 

                dwellingClass dwelling = new dwellingClass(age, region,  lmed, fmr, extremelyLowIncome, veryLowIncome, lowIncome, bedrooms, value, rooms, utility);
                alist.add(dwelling);

            }
            input.close();

        } catch (Exception a) {
            a.printStackTrace();
            System.exit(0);
        };
        for (dwellingClass each : alist) {
            System.out.println(each.getAge() + each.getRegion());
        }
        System.out.println(alist.get(0).getAge()); 
    }
}

【问题讨论】:

  • 另外,我无法打印出最后一行(getAge)。
  • NumberFormatExceptionparseInt 无法将字符串值解析为整数时返回。因此,您需要查看数据以确保您以正确的顺序读取整数和双精度数。要调试问题,您可以打印出 String 数组 info 中的每个值,以确保它是您所期望的。
  • 您能否在输入中包含导致错误的文件?
  • 我在这个输入文件上运行了你的代码,它没有出现任何异常: 输入文件的第一行:1 2 1.1 2.2 3.3 4.4 5.5 1 7.7 8 9.9 输入文件的第二行:11 12 11.1 12.2 13.3 14.4 15.5 11 17.7 18 19.9
  • 谢谢大家的帮助!如果有人愿意,我发布了我想出的解决方案,但我仍然不明白为什么我的原始代码返回了这些错误。

标签: java oop parsing arraylist delimiter


【解决方案1】:

首先你可以这样读取文件:

Scanner in = new Scanner(new FileReader("2007.txt"));

其次,要解析空格,您需要使用以下内容:

yourString.split("\\s+");

所以你的这一行应该变成:

String[] info = line.split("\\s+");

然后您可以按照您的方式访问您的String

但请确保您将正确的值(即正确的类型)传递给每个方法,否则您将收到您遇到的错误。

【讨论】:

  • 问题说分隔符是单个空格,而您的模式将匹配多个空格。
  • 您也可以使用new Scanner(new File("2007.txt")) 读取文件,这就是问题代码的作用,那么这样做的意义何在? --- 问题说“分隔符是单个空格,而不是空格,因此将line.split(" ") 更改为split("\\s+") 不会有任何区别。 --- 所以,看起来只有你答案的最后一句话实际上是在说任何有用的东西。
【解决方案2】:

您应该对从文件中读取的字符串进行数字验证,并确保它符合构建您的住宅类对象的要求。

String line = scanner.nextLine();
String[] info = line.split("\\s+");
boolean validInput = true;
//loop through your info array and check each number is valid beforehand
for(int i = 0; i < info.length; i++)
{
    if(!info[i].matches("\\d"))
    {
        validInput = false;
        break;
    }
}

//now we want to make sure our input was valid or else we don't create the object
if(info.length == 11 && validInput == true)
{
    dwellingClass dwelling = new dwellingClass(
        Integer.parseInt(info[0]), 
        Integer.parseInt(info[1]),
        Double.parseDouble(info[2]), 
        Double.parseDouble(info[3]), 
        Double.parseDouble(info[4]), 
        Double.parseDouble(info[5]), 
        Double.parseDouble(info[6]), 
        Integer.parseInt(info[7]), 
        Double.parseDouble(info[8]), 
        Integer.parseInt(info[9]), 
        Double.parseDouble(info[4]));
    alist.add(dwelling);
}

如果你把它放在你的 while 循环中,它只会创建从文件中读取的仅包含数字且包含 11 位数字的行的对象,其他行将被忽略。即使行格式不正确,这也允许执行文件。

【讨论】:

    【解决方案3】:

    您正在创建一个新文件,而不是加载您的文件。要加载文件,您需要使用文件输入流。您的扫描仪不会在新文件中找到任何内容,因此它全部为 Null


    我已纠正,语法正确,这将加载现有文件。正如其他人在上面提到的那样,这是一个数据问题

    【讨论】:

    • 根据docs.oracle.com/javase/7/docs/api/java/util/Scanner.html,这是扫描仪的有效用法:Scanner sc = new Scanner(new File("myNumbers"));
    • 非常反直觉,但我猜还可以
    • 就像 Pritam 说的那样,这可能会导致空格失败,这可能就是原因,在常规编辑器中检查您的文件,方法是搜索一个制表符后跟空格或空格后跟一个制表符
    • 您为什么认为创建了一个新文件?如果文件已经存在,Scanner(File) 构造函数会抛出 FileNotFoundException,因此它从不创建新文件。
    • 是的,我已经纠正了,我检查了文档并发现语法非常不直观,我想这是因为它不是我在网络应用程序中经常做的事情。从来不需要从本地加载,大多数时候甚至不允许。但通常在使用 new 初始化一个对象时,它是一个新对象,并且 JVM 外部的任何东西都会从 JPA 或某种形式的 InputStream 加载,因此 new File("myfile.txt") 似乎关闭了
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多