0

我在 Java 中读取文件时遇到了一些问题。

文件是什么样子的:

Answer 1:
1. This is an apple
2. Something
Answer 2:
1. This is a cool website 
2. I love banana
3. This is a table
4. Programming is fun
Answer 3. 
1. Hello World
.... 

我想要做的是将它们分成两项:一项是答案编号;另一个是答案列表。

因此,假设我有一个名为 Answer: String of answer number List of answers 的对象类。

到目前为止,这是我在将代码放入对象类之前调试代码所做的工作。但我无法得到正确的结果

public void reader(String file) throws FileNotFoundException, IOException {
    FileReader fR = new FileReader(file);
    BufferedReader bR = new BufferedReader(fR);
    String line = null;

    int count = 0 ;
    String blockNum = "";
    String printState = "" ;
    while ((line = bR.readLine()) != null) {
        if(line.contains("Answer")){
            //System.out.println("Contain Answer statement: " + line);
            count++;
            blockNum = line; 
            printState = "";
        }
        else{
            //System.out.println("No Answer Statement: " + line);
            printState += line + " / " ;
        }

        System.out.println( count + " " + blockNum + "   " + printState );
    }

    // Close the input stream
    bR.close();
    fR.close();
}

我很确定我在编码时做了一些愚蠢的事情。我不太确定如何阅读它,以便将它分开。

现在输出如下所示:

1 Answer 1:   
1 Answer 1:   1. This is an apple / 
1 Answer 1:   1. This is an apple / 2. Something / 
2 Answer 2:   
2 Answer 2:   1. This is a cool website  / 
2 Answer 2:   1. This is a cool website  / 2. I love banana / 
2 Answer 2:   1. This is a cool website  / 2. I love banana / 3. This is a table / 
2 Answer 2:   1. This is a cool website  / 2. I love banana / 3. This is a table / 4. Programming is fun / 
3 Answer 3.    
3 Answer 3.    1. Hello World / 

但我希望输出是这样的:

1 Answer 1:   1. This is an apple / 2. Something / 
2 Answer 2:   1. This is a cool website  / 2. I love banana / 3. This is a table / 4. Programming is fun /    
3 Answer 3.    1. Hello World / 
4

4 回答 4

4

您正在为您读取的每一行输入打印一行输出。尝试将 println 移动到检查答案的循环部分内,以确保只打印每个答案/答案值集一次。例如:

if(line.contains("Answer")) {
    if (printState != "") {
        System.out.println(count + " " + blockNum + "   " + printState);
    }
    ...
}

编辑:您还需要在退出 while 循环时进行打印,以确保打印最后一个答案/答案值集。

于 2012-05-11T18:34:34.920 回答
1

一种解决方案使用 printTime 的标志作为布尔值。

boolean printTime = false;

...
   if(line.contains("Answer")) {

       if (printTime!= false) {
          System.out.println( count + " " + blockNum + "   " + printState );
          printTime=false;
       }
        ...
  }else{
        //System.out.println("No Answer Statement: " + line);
        printState += line + " / " ;
        printTime=true; // you have one answer 
  }
  ...    

在最后一个答案的最后添加一点额外的打印

这样,您可以在一行中为一个答案提供多个 printState。

但正确的“java”处理方式是创建你的对象:

List<Answer> listOfAnswer = new LinkedList<Answer>();
Answer answer;
...
if(line.contains("Answer")){
            //System.out.println("Contain Answer statement: " + line);
            count++;

            answer = new Answer(line);
            listOfAnswer.add(answer)
        }
        else{
            answer.add(new Answer(line));
        }
}
...

并且只有在打印出来之后:)

System.out.println(listOfAnswer.toString());

更简单的解决方案是使用

Map<Integer, LinkedList<String>> answers = new LinkedHashMap<Integer, LinkedList<String>();
于 2012-05-11T18:44:01.970 回答
1

请参阅工作示例:

public void reader(String file) throws FileNotFoundException,
        IOException {
    BufferedReader reader = new BufferedReader(new FileReader(file));
    String line = "";
    while (reader.ready()) {
        line = reader.readLine();
        if (!line.contains("Answer")) {
            System.out.print(line + " / ");
        } else {
            System.out.println();
            System.out.print(line + " ");
        }
    }
}
于 2012-05-11T18:58:12.883 回答
1

主要输出问题是您在行迭代循环(while)内打印。

要解决它,您可以按照@Albion 回答的内容并更改在 内完成打印的位置while,但正如他回答中的 EDIT 所述,存在缺陷,您必须在循环后打印额外的时间,以便得到正确的结果。

有另一种艰难的方法,那就是根本不在循环内打印它,我认为这是你的情况的正确方法。要做到这一点,您只需要使用 StringBuilder 而不是 String!


我还发现了一些不必要的变量,并且使用该if(line.contains("Answer"))方法也存在缺陷,即如果“Answer”字符串出现在其中一个选项文本中,它会得到一个真实的结果并弄乱你的结果,例如:

Answer 1:
1. This is an apple
2. Capitalizing Is The Answer!
3. Something

将输出:

1 Answer 1:  1. This is an apple / 
2 2. Capitalizing Is The Answer!  3. Something

在大多数情况下,找到动态模式的最佳方法(就像你的那样,因为它改变了数字,并且在最后一个答案中,' :' 也带有 ' .')是使用(模式)匹配器!我使用了这个:if(line.matches("Answer \\d[\\:\\.]")),如果您还不习惯,请参阅Pattern Docs,因为String.matches()这是您在处理文本时可能会经常使用的东西。


解释每一个变化有点麻烦,代码很简单,你分析完就可以掌握了,所以我简单地发布一下我的方法:

public static void StackAnswer(String file) throws FileNotFoundException, IOException{
    BufferedReader br = new BufferedReader(new FileReader(file));
    StringBuilder output = new StringBuilder();
    int count = 0;
    while(br.ready()){
        String line = br.readLine().trim();
        if(line.matches("Answer \\d[\\:\\.]")){
            count++;
            output.append(System.lineSeparator()).append(count).append(' ').append(line);
        } else {
            output.append(" / ").append(line);
        }
    }
    System.out.println(output.toString().trim());
    br.close();
}

祝你好运!

于 2012-05-11T20:14:38.777 回答