AP Computer Science a Quiz: Using Text Files
10 questions · exam conditions
0:00
Using Text FilesQuestion 1 of 10

A program needs to read student grades from a text file called "grades.txt" where each line contains a student name followed by three test scores separated by spaces. Example line: "John Smith 85 92 78"

Which code segment will correctly read all data from the file and calculate each student's average, assuming the file exists and is properly formatted?

Scanner file = new Scanner(new File("grades.txt")); while(file.hasNextLine()) { String name = file.next() + " " + file.next(); int avg = (file.nextInt() + file.nextInt() + file.nextInt()) / 3; System.out.println(name + ": " + avg); }
Scanner file = new Scanner(new File("grades.txt")); while(file.hasNextLine()) { String line = file.nextLine(); String[] parts = line.split(" "); String name = parts[0] + " " + parts[1]; double avg = (Integer.parseInt(parts[2]) + Integer.parseInt(parts[3]) + Integer.parseInt(parts[4])) / 3.0; System.out.println(name + ": " + avg); }
Scanner file = new Scanner(new File("grades.txt")); while(file.hasNext()) { String name = file.next() + " " + file.next(); double avg = (file.nextInt() + file.nextInt() + file.nextInt()) / 3.0; System.out.println(name + ": " + avg); }
Scanner file = new Scanner(new File("grades.txt")); while(file.hasNextLine()) { String line = file.nextLine(); Scanner lineScanner = new Scanner(line); String name = lineScanner.next() + " " + lineScanner.next(); double avg = (lineScanner.nextInt() + lineScanner.nextInt() + lineScanner.nextInt()) / 3.0; System.out.println(name + ": " + avg); }
← Back to quizzes

AP Computer Science a Quiz

AP Computer Science a Quiz: Using Text Files

Practice Using Text Files in AP Computer Science a with focused quiz questions that help you check what you know, review explanations, and build confidence with test-style prompts.

What this quiz covers

This quiz focuses on Using Text Files, giving you a quick way to practice the rules, question types, and explanations that matter most for AP Computer Science a.

How to use this quiz

Try each quiz question before looking at the correct answer. Use the explanations to review missed ideas, then come back to similar questions until the pattern feels familiar.

All questions

Question 1

A program needs to read student grades from a text file called "grades.txt" where each line contains a student name followed by three test scores separated by spaces. Example line: "John Smith 85 92 78"

Which code segment will correctly read all data from the file and calculate each student's average, assuming the file exists and is properly formatted?

  1. Scanner file = new Scanner(new File("grades.txt")); while(file.hasNextLine()) { String name = file.next() + " " + file.next(); int avg = (file.nextInt() + file.nextInt() + file.nextInt()) / 3; System.out.println(name + ": " + avg); }
  2. Scanner file = new Scanner(new File("grades.txt")); while(file.hasNextLine()) { String line = file.nextLine(); String[] parts = line.split(" "); String name = parts[0] + " " + parts[1]; double avg = (Integer.parseInt(parts[2]) + Integer.parseInt(parts[3]) + Integer.parseInt(parts[4])) / 3.0; System.out.println(name + ": " + avg); }
  3. Scanner file = new Scanner(new File("grades.txt")); while(file.hasNext()) { String name = file.next() + " " + file.next(); double avg = (file.nextInt() + file.nextInt() + file.nextInt()) / 3.0; System.out.println(name + ": " + avg); }
  4. Scanner file = new Scanner(new File("grades.txt")); while(file.hasNextLine()) { String line = file.nextLine(); Scanner lineScanner = new Scanner(line); String name = lineScanner.next() + " " + lineScanner.next(); double avg = (lineScanner.nextInt() + lineScanner.nextInt() + lineScanner.nextInt()) / 3.0; System.out.println(name + ": " + avg); } (correct answer)

Explanation: Choice D correctly uses hasNextLine() to check for more lines, reads each complete line with nextLine(), then uses a separate Scanner to parse the line contents. This handles the mixed data types (strings and integers) on each line properly. Choice A uses integer division which truncates results. Choice B assumes exactly 5 space-separated parts but names could vary in length. Choice C uses hasNext() instead of hasNextLine() which could cause issues with line boundaries.

Question 2

A method processes a text file containing product data. Each line has format "ProductName,Price,Quantity". The method should return the total value of all products. Which implementation correctly handles potential file reading errors?

  1. try { Scanner sc = new Scanner(new File("products.txt")); double total = 0; while(sc.hasNextLine()) { String[] parts = sc.nextLine().split(","); total += Double.parseDouble(parts[1]) * Integer.parseInt(parts[2]); } return total; } catch(Exception e) { return -1; }
  2. Scanner sc = new Scanner(new File("products.txt")); double total = 0; try { while(sc.hasNextLine()) { String[] parts = sc.nextLine().split(","); total += Double.parseDouble(parts[1]) * Integer.parseInt(parts[2]); } } catch(FileNotFoundException e) { return -1; } return total;
  3. try { Scanner sc = new Scanner(new File("products.txt")); double total = 0; while(sc.hasNextLine()) { String[] parts = sc.nextLine().split(","); total += Double.parseDouble(parts[1]) * Integer.parseInt(parts[2]); } sc.close(); return total; } catch(FileNotFoundException e) { return -1; } (correct answer)
  4. Scanner sc; try { sc = new Scanner(new File("products.txt")); } catch(FileNotFoundException e) { return -1; } double total = 0; while(sc.hasNextLine()) { String[] parts = sc.nextLine().split(","); total += Double.parseDouble(parts[1]) * Integer.parseInt(parts[2]); } return total;

Explanation: Choice C properly wraps the entire file operation in a try-catch block, handles FileNotFoundException specifically, and closes the Scanner. Choice A catches all exceptions but doesn't close the Scanner. Choice B has the Scanner creation outside the try block, so FileNotFoundException won't be caught. Choice D handles file creation errors but not parsing errors that could occur during reading, and doesn't close the Scanner.

Question 3

A text file "data.txt" contains multiple sections separated by blank lines. Each section has a header line followed by data lines. A program needs to process each section separately.

Which approach will correctly identify section boundaries and group the data appropriately?

  1. Read all lines into an ArrayList, then iterate through looking for empty strings to identify section breaks and process groups between breaks
  2. Use hasNextLine() in a loop, read each line, and when an empty line is found, process the accumulated section data before starting a new section (correct answer)
  3. Read the entire file as one string using Scanner.useDelimiter("\Z"), then split on double newlines to separate sections
  4. Use hasNext() to read tokens, collecting them until no more tokens exist on the current line, then move to the next section

Explanation: Choice B correctly processes the file sequentially, accumulating lines for each section and processing when a blank line (section separator) is encountered. This is memory-efficient and handles sections as they're found. Choice A loads the entire file into memory unnecessarily. Choice C assumes sections are separated by double newlines, but the problem states blank lines separate sections. Choice D misunderstands the structure by working with tokens instead of lines.

Question 4

When reading numeric data from a text file using Scanner methods, which statement about mixing nextInt() and nextLine() calls is most accurate?

  1. nextInt() automatically advances to the next line, so nextLine() can be called immediately after without issues
  2. nextInt() leaves the newline character in the buffer, so nextLine() should be called once to consume it before reading the next meaningful line (correct answer)
  3. nextInt() and nextLine() cannot be mixed in the same Scanner object due to different parsing mechanisms
  4. nextInt() consumes the entire current line including the newline, so the next nextLine() call will read from the following line correctly

Explanation: Choice B correctly identifies that nextInt() reads only the integer value and leaves the newline character in the input buffer. A subsequent nextLine() call will read that remaining newline, returning an empty string. An extra nextLine() call is needed to consume the leftover newline. Choice A is incorrect because nextInt() doesn't advance past the newline. Choice C is wrong as they can be mixed with proper handling. Choice D incorrectly states that nextInt() consumes the newline.

Question 5

A program processes a log file where each line contains a timestamp followed by tab-separated values. The number of values per line varies, and some values may be empty.

Which code segment will correctly parse each line and handle the variable number of fields, including empty ones?

  1. String[] parts = line.split("\t"); for(int i = 1; i < parts.length; i++) { if(!parts[i].isEmpty()) processValue(parts[i]); }
  2. String[] parts = line.split("\t", -1); for(int i = 1; i < parts.length; i++) { processValue(parts[i].trim()); } (correct answer)
  3. Scanner lineScanner = new Scanner(line).useDelimiter("\t"); lineScanner.next(); while(lineScanner.hasNext()) { String value = lineScanner.next(); if(value.length() > 0) processValue(value); }
  4. String[] parts = line.split("\t"); for(String value : parts) { if(value != null && !value.equals("")) processValue(value.trim()); }

Explanation: Choice B correctly uses split() with limit -1 to preserve empty fields (trailing empty fields would be discarded with default split), starts from index 1 to skip the timestamp, and processes all values including empty ones after trimming. Choice A doesn't preserve empty fields and skips them. Choice C with Scanner.useDelimiter() won't preserve empty fields between consecutive delimiters. Choice D processes the timestamp (index 0) and doesn't preserve empty trailing fields.

Question 6

A method reads student records from "students.txt" where each line contains "LastName,FirstName,GPA". It should return a Map<String, Double> with full names as keys and GPAs as values. Which implementation correctly handles the file structure and potential parsing errors?

  1. Map<String, Double> students = new HashMap<>(); try(Scanner sc = new Scanner(new File("students.txt"))) { while(sc.hasNextLine()) { String[] parts = sc.nextLine().split(","); if(parts.length == 3) { String fullName = parts[1].trim() + " " + parts[0].trim(); students.put(fullName, Double.parseDouble(parts[2].trim())); } } } catch(Exception e) { return null; } (correct answer)
  2. Map<String, Double> students = new HashMap<>(); Scanner sc = new Scanner(new File("students.txt")); while(sc.hasNextLine()) { String line = sc.nextLine(); String[] parts = line.split(","); String fullName = parts[1] + " " + parts[0]; students.put(fullName, Double.valueOf(parts[2])); } sc.close(); return students;
  3. Map<String, Double> students = new HashMap<>(); try(Scanner sc = new Scanner(new File("students.txt"))) { while(sc.hasNext()) { String lastName = sc.next(); String firstName = sc.next(); double gpa = sc.nextDouble(); students.put(firstName + " " + lastName, gpa); } } catch(IOException e) { return students; }
  4. Map<String, Double> students = new HashMap<>(); try(Scanner sc = new Scanner(new File("students.txt"))) { while(sc.hasNextLine()) { String[] parts = sc.nextLine().split(","); String fullName = parts[1].trim() + " " + parts[0].trim(); try { students.put(fullName, Double.parseDouble(parts[2].trim())); } catch(NumberFormatException e) { continue; } } } catch(FileNotFoundException e) { return students; }

Explanation: Choice A uses try-with-resources for automatic resource management, validates that each line has exactly 3 parts before processing, trims whitespace, constructs the full name correctly (FirstName LastName), and handles all exceptions appropriately. Choice B doesn't handle exceptions and doesn't validate line format. Choice C incorrectly assumes comma-separated data can be read with next() and nextDouble(), and catches the wrong exception type. Choice D has nested try-catch which is unnecessarily complex and doesn't validate the array length.

Question 7

A text file contains survey responses where each line represents one response with multiple choice answers (A, B, C, or D) for 10 questions, with no separators between answers. Example: "ABCDABCDAB"

Which code segment will correctly count how many respondents chose answer 'C' for question 5?

  1. int count = 0; Scanner file = new Scanner(new File("survey.txt")); while(file.hasNextLine()) { String response = file.nextLine(); if(response.length() >= 5 && response.charAt(4) == 'C') count++; }
  2. int count = 0; Scanner file = new Scanner(new File("survey.txt")); while(file.hasNextLine()) { String response = file.nextLine(); if(response.substring(4, 5).equals("C")) count++; }
  3. int count = 0; Scanner file = new Scanner(new File("survey.txt")); while(file.hasNextLine()) { String response = file.nextLine(); if(response.length() == 10 && response.charAt(5) == 'C') count++; }
  4. int count = 0; Scanner file = new Scanner(new File("survey.txt")); while(file.hasNextLine()) { String response = file.nextLine().trim(); if(response.length() >= 10 && response.charAt(4) == 'C') count++; } (correct answer)

Explanation: Choice D correctly trims the line (removing potential whitespace), validates the response has at least 10 characters, and checks position 4 (which is question 5, since array indexing starts at 0). Choice A doesn't trim and only checks length >= 5 instead of >= 10. Choice B doesn't validate length and could throw StringIndexOutOfBoundsException. Choice C checks charAt(5) which would be question 6, not question 5.

Question 8

A program needs to read a large text file and find all lines containing a specific keyword. Which approach is most memory-efficient for processing files that may be too large to fit entirely in memory?

  1. Use Files.readAllLines() to load the entire file into a List, then iterate through the list checking each line for the keyword
  2. Use Scanner with hasNextLine() and nextLine() to read one line at a time, checking each line for the keyword before reading the next (correct answer)
  3. Use BufferedReader.lines() to create a Stream, then use filter() and forEach() to process lines containing the keyword
  4. Read the entire file into a single String using Scanner.useDelimiter("\Z"), then use String.split() to process individual lines

Explanation: Choice B is most memory-efficient because it reads and processes one line at a time, keeping only the current line in memory. This approach can handle arbitrarily large files. Choice A loads the entire file into memory at once. Choice C creates a stream but may still buffer large portions of the file. Choice D loads the entire file as one string, which is the least memory-efficient approach.

Question 9

A program reads a configuration file where each line contains a key-value pair separated by an equals sign (e.g., "timeout=30"). The program should store these in a HashMap. What is the most robust approach to handle lines that don't follow the expected format?

  1. Split each line on "=", check that the resulting array has exactly 2 elements, then add to the HashMap if valid, otherwise skip the line completely
  2. Split each line on "=", use the first element as key and join remaining elements as value, ensuring all lines are processed even if malformed
  3. Use indexOf("=") to find the separator, split the line at that position, and add to HashMap only if the separator exists and creates non-empty key-value pairs (correct answer)
  4. Split each line on "=" with a limit of 2, check for exactly 2 parts with non-empty keys, and skip lines that don't meet criteria

Explanation: Choice C is most robust because indexOf() allows checking if the separator exists before splitting, and it can handle cases where the value itself contains "=" characters. Choice A fails if values contain "=" since split() would create more than 2 elements. Choice B processes malformed lines which could add invalid entries. Choice D's split with limit 2 is better but doesn't verify the separator actually exists before splitting.

Question 10

A text file "scores.txt" contains integer test scores, one per line. Some lines may be empty or contain non-numeric data that should be skipped.

Which code segment will correctly read only valid integer scores from the file and add them to an ArrayList, skipping invalid entries without crashing?

  1. ArrayList scores = new ArrayList<>(); Scanner file = new Scanner(new File("scores.txt")); while(file.hasNextLine()) { String line = file.nextLine().trim(); if(!line.isEmpty()) { try { scores.add(Integer.parseInt(line)); } catch(NumberFormatException e) { continue; } } } (correct answer)
  2. ArrayList scores = new ArrayList<>(); Scanner file = new Scanner(new File("scores.txt")); while(file.hasNextInt()) { scores.add(file.nextInt()); if(file.hasNextLine()) file.nextLine(); }
  3. ArrayList scores = new ArrayList<>(); Scanner file = new Scanner(new File("scores.txt")); while(file.hasNextLine()) { String line = file.nextLine(); if(line.trim().length() > 0 && file.hasNextInt()) { scores.add(Integer.parseInt(line)); } }
  4. ArrayList scores = new ArrayList<>(); Scanner file = new Scanner(new File("scores.txt")); while(file.hasNextLine()) { try { String line = file.nextLine().trim(); if(!line.isEmpty()) scores.add(Integer.parseInt(line)); } catch(Exception e) { System.out.println("Skipped invalid line"); } }

Explanation: Choice A correctly reads each line, trims whitespace, checks for empty lines, and uses try-catch to handle NumberFormatException when parsing fails. Choice B uses hasNextInt() which doesn't handle invalid data well and the nextLine() call is problematic. Choice C incorrectly uses hasNextInt() after already reading the line, and parseInt() on a line that may not be valid. Choice D is close but catches all exceptions unnecessarily broadly and includes debugging output.