Question

I have a txt file that has ~900 questions that look like this:

On to the questions:

-----------------------------------------------------------------------------
  #0001 Which disease devastated livestock across the UK during 2001?
-----------------------------------------------------------------------------
 *Hand-and-foot
 *Foot-in-mouth
 *Hand-to-mouth
 *Foot-and-mouth

Answer: Foot-and-mouth

-----------------------------------------------------------------------------
  #0002 Which of these kills its victims by constriction?
-----------------------------------------------------------------------------
 *Andalucia
 *Anaconda
 *Andypandy
 *Annerobinson

Answer: Anaconda

I have an object that stores the question, and objects that store the answer

IE: Question.java

public class Question {
    private String questionText;
    private Answer a, b, c, d;

    public Question(String questionText, Answer a, Answer b, Answer c, Answer d) {
        this.questionText = questionText;
        this.a = a;
        this.b = b;
        this.c = c;
        this.d = d;
    }

    public String getQuestionText() {
        return questionText;
    }

    public void setQuestionText(String questionText) {
        this.questionText = questionText;
    }

    public Answer getA() {
        return a;
    }

    public void setA(Answer a) {
        this.a = a;
    }

    public Answer getB() {
        return b;
    }

    public void setB(Answer b) {
        this.b = b;
    }

    public Answer getC() {
        return c;
    }

    public void setC(Answer c) {
        this.c = c;
    }

    public Answer getD() {
        return d;
    }

    public void setD(Answer d) {
        this.d = d;
    }

    public String toString() {
        return  questionText +
                "\nA) " + a +
                "\nB) " + b +
                "\nC) " + c +
                "\nD) " + d;
    }
}

Answers.Java

public class Answer {
    private String answerText;
    private boolean correct;

    //constructor to set correct answer
    public Answer(String answerText, boolean correct) {
        this.answerText = answerText;
        this.correct = correct;
    }

    public Answer(String answerText) {
        this.answerText = answerText;
        this.correct = false;
    }

    public String getAnswerText() {
        return answerText;
    }

    public void setAnswerText(String answerText) {
        this.answerText = answerText;
    }

    public boolean isCorrect() {
        return correct;
    }

    public void setCorrect(boolean correct) {
        this.correct = correct;
    }

    public String toString() {
        return answerText;
    }
}

I would like to make an array list that stores all the question objects parsed from the text file. I'm new to Java and programmed primarily in python before, and am a bit confused on how to do text file parsing in java as it seems a lot more complex. I know how to parse like line by line or a list of words for example. I don't know how to do it with the extra text in the file.

Any help would be appreciated.

Sample of two line question:

-----------------------------------------------------------------------------
  #0016 Which word follows 'North' and 'South' to give the names of two
        continents?
-----------------------------------------------------------------------------
 *Africa
 *America
 *Asia
 *Australia

Answer: America
Was it helpful?

Solution

Hi there here is something that might do the trick ;)

    String file = "text.txt";
    BufferedReader br = null;
    int nbAnswer = 4;
    try {
        br = new BufferedReader(new FileReader(file));
        String line;
        while((line = br.readLine()) != null) {   
            if( line.contains("-----------"))
            {
                line = br.readLine();
                String question = line.split("#[0-9]{4} ")[1];
                while(!(line = br.readLine()).contains("-----------"))
                    question += " " + line.trim();

                String[] answers = new String[4];

                for( int i = 0; i < nbAnswer; i++)
                    answers[i] = br.readLine().substring(2);

                br.readLine();
                String sol = br.readLine().split("Answer: ")[1];
                System.out.println(question + "\nanswer: " + answers[0] + " " + answers[1] + " " + answers[2] + " " + answers[3] + "\nsol " + sol);
            }
        }
    }
    catch(IOException ex) {
        System.err.println(ex);
    }

line.split("#[0-9]{4} ")[1]; is a regex that will allow you to split the string after a # followed by 4 numbers and a space.

At least it's a good beginning ;)

PS: There are many wrong thing about doing a beautiful .txt containing the questions etc.

  1. It's harder to parse
  2. It's bigger in size

You could for example change *Foot-and-mouth to (*)Foot-and-mouth to indicate that this is the answer instead of having 2 more lines for it ;)

OTHER TIPS

Implement a simple FSM and parse it line by line. Read until you find a line that starts with #dddd, then read until you find a line that starts with -. Those lines make up a question. Read until you find a line that starts with a *, then read until you hit a blank line. Those are your choices. Next read until you find a line that starts with Answer, that's your answer. Repeat.

If each your question takes exactly 10 lines in a file, it's much simply to parse it line-by-line, getting mean of each record from its position, not content:

public class Parse {
    public static final int OPTION_PREFIX_LENGTH = "*".length();
    public static final int ANSWER_PREFIX_LENGTH = "Answer: ".length();
    public static final String QUESTION_SEPARATOR = "-----------------------------------------------------------------------------";

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("/Users/Marboni/tmp/test.txt"));

        try {
            while (br.ready()) {
                br.readLine();                                     // Skip separator (----).

                StringBuilder questionBuilder = new StringBuilder();
                String questionLine;
                while (!QUESTION_SEPARATOR.equals(questionLine = br.readLine())) {  // Reading lines and add them to question until separator.
                    questionBuilder.append(questionLine.trim()).append(' ');
                }
                String questionText = questionBuilder.toString().trim();
                String a = parseQuestion(br.readLine());           // Option a).
                String b = parseQuestion(br.readLine());           // Option b).
                String c = parseQuestion(br.readLine());           // Option c).
                String d = parseQuestion(br.readLine());           // Option d).
                br.readLine();                                     // Skip blank line.
                String answer = parseAnswer(br.readLine());        // Answer.

                if (br.ready()) {
                    br.readLine();                         // Skip blank line between questions, if exists.
                }

                Question question = new Question(questionText,
                        new Question.Answer(a, answer.equals(a)),
                        new Question.Answer(b, answer.equals(b)),
                        new Question.Answer(c, answer.equals(c)),
                        new Question.Answer(d, answer.equals(d))
                        );

                // Do something with it.
            }
        } finally {
            br.close();
        }
    }

    private static String parseQuestion(String record) {
        return record.trim().substring(OPTION_PREFIX_LENGTH);
    }

    private static String parseAnswer(String record) {
        return record.trim().substring(ANSWER_PREFIX_LENGTH);
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top