【问题标题】:Parsing input from a text file解析来自文本文件的输入
【发布时间】:2013-09-14 19:07:27
【问题描述】:

我有一个包含员工信息的文本文件。第一个单词是员工的姓氏,第二个单词是名字。字符代码 h 或 s 告诉我他们是什么类型的员工,有薪或按小时计酬。最后,字符代码后面的数字是小时工资(如果是小时工)或年薪(如果是受薪员工)。

Smith, John   h   5.00
Potter, Harry   s   10000

我想要对这些信息执行的操作是扫描文本文件以根据识别的字符代码自动创建新的受薪员工对象或小时工对象。

这些是每小时雇员对象的参数。

public HourlyEmployee(String first, String last, double wage)

这是我想出来的。

File input = new File("EmployeesIn.txt"); 
Scanner in = new Scanner(input);


while(in.hasNextLine()) {
    int i = 1;
    String line =(in.nextLine());
    if (line.contains(" h ")) {
        HourlyEmployee Employee1 = new HourlyEmployee(in.next(),in.next(),in.nextDouble());
        System.out.println(Employee1);  

这段代码的问题是我从 in.nextDouble(); 中得到了 InputMismatchException。

所以我编辑了我的代码以手动将工资分配给 1,以至少查看它是否正确分配了姓氏和名字,但它甚至没有正确执行。它使用错误的行来分配值,并将 First Name 分配为 last name,将 Last Name 作为 first name。

Harry, Potter,  $1.0/hour

所以我的问题是,我该如何正确地做到这一点?根据我提供的文本文件,我想使用这些参数创建一个 HourlyEmployee 对象

HourlyEmployee Employee1 = new HourlyEmployee(Smith,John,5.00);

【问题讨论】:

  • 也许您应该考虑在文本文件中包含分隔符,例如 ;#,并使用 FileReader 而不是扫描仪,并使用 split()StringTokenizer 方法来标记行
  • 我认为您可能会在“h”上调用in.nextDouble()。还请记住,逗号将被捕获并成为名称的一部分(即“Smith”的姓氏)

标签: java parsing filereader


【解决方案1】:

两个明显的问题:

由于您是按顺序读取文件的,因此您首先读取的是姓氏;但是您的HourlyEmployee 需要的第一个参数是名字。其次,您第三次尝试读取文件最终将读取“h”或“s”标志,而不是支付。解决方法:分别读入名字,然后调用函数。像这样的:

while(in.hasNextLine()) {
  lastName = in.next();
  firstName = in.next();
  payType = in.next(); // read the 'h' or 's'
  pay = in.nextDouble();
  switch(payType) {
    case 'h': 
      Employee1 = new HourlyEmployee(firstName, lastName, pay);
      break;
    case 's':
      Employee1 = new SalariedEmployee(firstName, lastName, pay);
      break;
    default:
      // warn about invalid format
  }
  System.out.println(Employee1);  
}

您可能需要从 lastName 变量中删除逗号 - 不确定您的函数是否已经解决了这个问题。

【讨论】:

  • 此代码有效,但它读取的是 Harry Potter 行而不是 John Smith 行。是什么原因造成的?
  • 因为在你读完一行看它是否包含'h'之后,你从头开始读下一行。省去line=in.nextline(); if(line.contains... 的东西,改用上面的东西。然后检查skipThis(可以重命名为payType)并根据内容进行切换。我需要提供完整的代码还是你可以从这里获取。
  • 是的,我明白了。最后一个问题。在运行 while 循环后是否有创建一个新的员工对象?像 HourlyEmployee Employee[i] 这样的东西?现在它只会创建一个名为 Employee1 的对象并继续重写它。
  • 当然——您可以创建这些对象的数组。只需记住以正确的大小声明它(或查看动态分配),并在每次循环时增加索引
【解决方案2】:

为什么只加载文件并逐行读取?

由于您的文件结构 - 相同,因此很容易解析/分割每一行

public static String loadFile(String filePath){



    try {           

        // Open the file that is the first command line parameter
        FileInputStream fstream = new FileInputStream(filePath);
        BufferedReader br = new BufferedReader(new InputStreamReader(fstream));

        String strLine = null;

        //Read File Line By Line
        while ((strLine = br.readLine()) != null  )   {

                            if(strLine.split("[ ]+").length > 3){
                               // do stuff here
                             }

        }// end while

        //Close the input stream            
        br.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    return buff.toString();
}

【讨论】:

  • 请不要对文本使用 DataInputStream。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-22
  • 1970-01-01
  • 1970-01-01
  • 2011-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多