简体   繁体   中英

Reading file with different lines and storing into variables

I have some questions regarding reading file inputs with varying lines. For example, I'm trying to read a file similar to that of a test. The first line of the file will have the name of the test. The second line has the question. The third line contains two integers, the first being responsible for the number of options in a multiple choice question, the second being the correct option. Finally, the next 'x' lines are the potential choices.

test file

Unit Exam 3
"What is the best color for a Mustang?"
4,1
Red
Blue
Black
White
"What year was the Mustang invented?"
3,3
1978
2015
1964
etc etc

 Scanner scnr = new Scanner(new FileInputStream("test.txt"));
    String line;
    while (scnr.hasNextLine()) {
        line = scnr.nextLine();
        String[] data = line.split(",");
String testTitle = data[0];

... This is where my question comes in as the next line is now NOT the test title, however, the location is still data[0] for this line.

Furthermore, the question continues onto the next part because now I'm dealing with the integer line. I know it would look something like:

int numOptions = Integer.parseInt(data[0]);
int correct = Integer.parseInt(data[1]);

But this would cause a slew of errors for the coding. Any idea how to do this?

FINALLY Note that not all questions have the same number of potential options. How would this change, for example, if there was a question that was True or False with only 2 options, compared to the first question in my sample test that has 4 questions?

If the structure of the input is correct you want to scan the question, then the answer data. The data you check the numbers of and get the next x lines as answer.

Example function:

void func(Scanner s) {
    String question = s.nextLine();
    String[] data = s.nextLine().split(",");
    String[] answers = new String[Integer.parseInt(data[0])];
    for (int i = 0; i < answers.length; i++) {
        answers[i] = s.nextLine();
    }
    int correct = Integer.parseInt(data[1]);
}

I would recommand using a function with a object return, but you could put this in your loop.

Keeping track of where you are in the Quiz file can be beneficial so some extent but what is particularly key is maintaining the same data structure throughout the quiz file as it is created.

I would think that normally, you would want to display the Quiz Title. In your example this is the very first line of the file. But what if you wanted to have comments in the quiz file, or the first line wasn't a Quiz Title. Something should be provided in the data to distinguish the title from other data, for example:

The UnitExam3.txt file:

# This test is about various Cars.
# Each correct answer applies as a single point.
# This test will be applied to Student's overall grade value.

Title: Unit Exam 3

"What is the best color for a Mustang?"
4,1
Red
Blue
Black
White

"What year was the Mustang invented?"
3,3
1978
2015
1964

As you can see, this quiz file is easy to read and work with. You can also see that the Quiz Title (Unit Exam 3) is prefixed with an attribute named Title: . This definitely distinguishes the title from anything else within the Quiz File and therefore make it easy to retrieve.

Individual Quiz Questions are easily distinguishable within the Quiz File because they are enclosed within quotation marks ("...") which is good since nothing else within each question has this feature. So, when a line is detected to start with a Quotation mark ( " ), we know it is the start of a new Quiz Question.

As you can see in the code below quiz question data is read hot from the Quiz File as it is needed. When a single question data is acquired it is then immediately displayed to console for the Student to answer. Once answered the Student is informed if the answer supplied is right or wrong and moved on to the read in the next Quiz Question.

// 'Try With Resources' is used here to auto-close the reader (scnr).
try (Scanner scnr = new Scanner(new File("UnitExam3.txt"))) {
    Scanner input = new Scanner(System.in);
    String line;
    String quizName;
    int questionCount = 0;
    int correct = 0;
    int wrong = 0;
    while (scnr.hasNextLine()) {
        line = scnr.nextLine().trim();
        // Skip any comment or blank lines (comment lines start withe a: #)
        if (line.equals("") || line.startsWith("#")) {
            continue;
        }
        // Is this line the title?
        if (line.toLowerCase().startsWith("title:")) {
            // Yes it is...
            quizName = line.substring(6).trim();
            // Display the Test Name To Console...
            System.out.println(quizName);
            // Underline it taking advantage of the String.join() 
            // and the Collection.nCopies() methods...
            System.out.println(String.join("", Collections.nCopies(quizName.length(), "=")));
        }
        // Is this line the start of a Quiz Question?
        else if (line.startsWith("\"")) {
            // Yes it is...
            questionCount++;    // increment question count
            // Remove quotes from question.
            String question = line.substring(1, line.length() - 1);
            // Get the rest of data for this particular question...
            // Get the Number of Choices and Answer line
            String questInfoLine = scnr.nextLine().trim();
            int numberofChoices = Integer.parseInt(questInfoLine.split("\\s{0,},\\s{0,}")[0]);
            String answerChoice = questInfoLine.split("\\s{0,},\\s{0,}")[1];
            // Get the multiple choice answers
            String[] choices = new String[numberofChoices];
            for (int i = 0; i < numberofChoices; i++) {
                choices[i] = scnr.nextLine().trim();
            }
            // Display the test question to Console...
            System.out.println();
            System.out.println("Question #" + questionCount + ":");
            System.out.println(question);
            for (int i = 0; i < choices.length; i++) {
                System.out.println((i + 1) + ") " + choices[i]);
            }
            System.out.print("Answer: --> ");
            // Wait for answer from Student...
            String answer = input.nextLine();
            // Check Answer...
            if (answer.equals(answerChoice)) {
                System.out.println("Correct");
                correct++;  // increment correct answer count
            }
            else {
                System.out.println("Wrong!");
                wrong++;    // increment wrong answer count
            }
        }
        // Continue reading in Quiz File Questions until end of file (EOF).
    }

    // Display Student results from the Quiz(add averaging etc if you like).
    System.out.println();
    System.out.println("========== Results ===========");
    System.out.println("Answers Correct: " + correct);
    System.out.println("Answers Wrong: " + wrong);
    System.out.println("==============================");
}
catch (FileNotFoundException ex) {
    System.err.println(ex);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM