Using Text Files
Help Questions
AP Computer Science A › Using Text Files
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(); 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); }
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); }
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.
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?
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;
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; }
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; }
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;
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.
Which approach will correctly identify section boundaries and group the data appropriately?
Use hasNext() to read tokens, collecting them until no more tokens exist on the current line, then move to the next section
Read all lines into an ArrayList, then iterate through looking for empty strings to identify section breaks and process groups between breaks
Read the entire file as one string using Scanner.useDelimiter("\Z"), then split on double newlines to separate sections
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
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.
When reading numeric data from a text file using Scanner methods, which statement about mixing nextInt() and nextLine() calls is most accurate?
nextInt() consumes the entire current line including the newline, so the next nextLine() call will read from the following line correctly
nextInt() automatically advances to the next line, so nextLine() can be called immediately after without issues
nextInt() and nextLine() cannot be mixed in the same Scanner object due to different parsing mechanisms
nextInt() leaves the newline character in the buffer, so nextLine() should be called once to consume it before reading the next meaningful line
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.
Which code segment will correctly parse each line and handle the variable number of fields, including empty ones?
String[] parts = line.split("\t", -1); for(int i = 1; i < parts.length; i++) { processValue(parts[i].trim()); }
String[] parts = line.split("\t"); for(int i = 1; i < parts.length; i++) { if(!parts[i].isEmpty()) processValue(parts[i]); }
String[] parts = line.split("\t"); for(String value : parts) { if(value != null && !value.equals("")) processValue(value.trim()); }
Scanner lineScanner = new Scanner(line).useDelimiter("\t"); lineScanner.next(); while(lineScanner.hasNext()) { String value = lineScanner.next(); if(value.length() > 0) processValue(value); }
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.
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?
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; }
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; }
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; }
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;
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.
Which code segment will correctly count how many respondents chose answer 'C' for question 5?
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++; }
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++; }
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++; }
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++; }
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.
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?
Read the entire file into a single String using Scanner.useDelimiter("\Z"), then use String.split() to process individual lines
Use BufferedReader.lines() to create a Stream
Use Files.readAllLines() to load the entire file into a List
Use Scanner with hasNextLine() and nextLine() to read one line at a time, checking each line for the keyword before reading the next
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.
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?
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
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
Split each line on "=", use the first element as key and join remaining elements as value, ensuring all lines are processed even if malformed
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.
Which code segment will correctly read only valid integer scores from the file and add them to an ArrayList, skipping invalid entries without crashing?
ArrayList
ArrayList
ArrayList
ArrayList
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.