Implemented method getting NullPointerException - java

I have an implemented method which visits the node of a binary tree. I have a word class which implements this through an interface called TreeComparable.
Here is the visit method:
#Override
public void visit() {
System.out.printf("%-15s%-7s", getWord(), count);
pw.printf("%-15s%-7s", getWord(), count);
ObjectListNode p = list.getFirstNode();
while (p != null) {
System.out.print(((LinePosition) p.getInfo()).getLineNumber() + "-" + ((LinePosition) p.getInfo()).getPosition() + " ");
pw.print(((LinePosition) p.getInfo()).getLineNumber() + "-" + ((LinePosition) p.getInfo()).getPosition() + " ");
p = p.getNext();
}
System.out.println();
pw.println();
}
I am getting errors with the PrintWriter Object. I am getting a nullPointerException. I have a default constructor that is part of the class that is implementing this visit method.
This is the default constructor being used when creating a word object.
public Word(PrintWriter pw) {
this.pw = pw;
}
Everything works if I comment out trying to write to the text file:
#Override
public void visit() {
System.out.printf("%-15s%-7s", getWord(), count);
//pw.printf("%-15s%-7s", getWord(), count);
ObjectListNode p = list.getFirstNode();
while (p != null) {
System.out.print(((LinePosition) p.getInfo()).getLineNumber() + "-" + ((LinePosition) p.getInfo()).getPosition() + " ");
//pw.print(((LinePosition) p.getInfo()).getLineNumber() + "-" + ((LinePosition) p.getInfo()).getPosition() + " ");
p = p.getNext();
}
System.out.println();
//pw.println();
}
however, for this assignment I need to print out the outputs to a text file. Why is the printwriter object not getting passed in correctly?Thanks for any input!
EDIT:
Here are a few places where I tried to call the constructor:
public class Query {
PrintWriter pw;
public Query(PrintWriter pw) {
this.pw = pw;
}
public void performQuery(ObjectBinaryTree t) {
Scanner userInput = new Scanner(System.in);
System.out.println("Search for word: ");
pw.println("Search for word: ");
Word word = new Word(pw);
String input = userInput.next();
do {
word = new Word(input);
if (t.searchBST(word) != null) {
ObjectTreeNode p = t.searchBST(word);
ObjectListNode q = ((Word) p.getInfo()).getList().getFirstNode();
System.out.printf("%-15s%-5s", ((Word) p.getInfo()).getWord(), ((Word) p.getInfo()).getCount());
pw.printf("%-15s%-5s", ((Word) p.getInfo()).getWord(), ((Word) p.getInfo()).getCount());
while (q != null) {
System.out.print(((LinePosition) q.getInfo()).getLineNumber() + "-" + ((LinePosition) q.getInfo()).getPosition() + " ");
q = q.getNext();
}
System.out.println("\nType 1 to exit, or press enter for new search: ");
pw.println("\nType 1 to exit, or press enter for new search: ");
input = userInput.next();
continue;
}
else
System.out.print("Word Not Found");
System.out.println("\nType 1 to exit, or press enter for new search: ");
pw.print("Word Not Found");
pw.println("\nType 1 to exit, or press enter for new search: ");
input = userInput.next();
continue;
} while (!input.equals("1"));
}
}
and:
public class Driver {
public static void main(String[] args) throws FileNotFoundException {
PrintWriter pw = new PrintWriter(new File("csis.txt"));
Word word = new Word(pw);
Xref xref = new Xref(pw);
Query query = new Query(pw);
xref.readWords();
System.out.println();
pw.println();
query.performQuery(xref.getBinaryTree());
pw.close();
}
}
EDIT:
The visit() method is part of this interface (not sure if this helps but...):
public interface TreeComparable {
int compareTo(Object o);
void operate(Object o);
void visit();
}

The problem is here:
String input = userInput.next();
do {
word = new Word(input);
You should be getting a compile-time error about that, but evidently Word has a constructor that takes a String rather than a PrintWriter, and that constructor isn't setting pw correctly. This assignment is throwing away the (correct) instantiation above:
Word word = new Word(pw);
It looks like you might be misunderstanding what is and isn't a static member of an object. All of the Word objects you instantiate with a PrintWriter carry around a non-null value for pw, but the rest have null unless you fix it. My guess is that your Word(String) constructor ignores pw and expects it to be set by some other call -- it won't.

Related

Retrieve lines in txt file and append new inputs from the user java

I'm using an arraylist to append inputs and send the arraylist elements to file. However, everytime I exit the program and run it again, the contents in the written in the file becomes empty.
ArrayList<String> memory = new ArrayList<String>();
public void fileHandling() {
try {
FileWriter fWriter = new FileWriter("notes.data");
for (int x = 0; x <= memory.size() - 1; x++) {
fWriter.write(memory.get(x) + '\n');
}
fWriter.close();
} catch (IOException e) {
System.out.println(e);
}
}
public void createNote() {
Scanner insertNote = new Scanner(System.in);
LocalDate todayDate = LocalDate.now();
LocalTime nowTime = LocalTime.now();
String timeFormat = nowTime.format(DateTimeFormatter.ofLocalizedTime(FormatStyle.MEDIUM));
String dateTime = todayDate.toString() + " at " + timeFormat;
while (true) {
System.out.println();
System.out.println("Enter a note");
System.out.print("> ");
String note = insertNote.nextLine();
if (note == null) {
System.out.println("Invalid input! Try again");
break;
} else {
memory.add(note + " /" + dateTime);
fileHandling();
System.out.println("Note is saved!\n");
break;
}
}
I expect the program to save the contents of every input. Then if I exit and run the program again, the contents will go back to the array
Your code currently does the following:
You enter something (X) for the first time:
It gets added to the ArrayList
The ArrayList gets written into the file
Your file now contains: X
You enter something second (Y):
It gets added to the ArrayList (Which now contains: X, Y)
The ArrayList gets written into the file
Your file now contains: X + newline + Y
Your Problem is, that everytime you create a new FileWrite it overwrites your file.
This can be avoided by using the constructor like this:
FileWriter writer = new FileWriter("notes.data", true);
This sets it into the append mode and therefore keeps previous data in the file
You don't need to create a separate Scanner, in method createNote(), in order to get a "note" from the user.
It is usually better to write your code using the interface rather than the specific implementation because then you usually need to change less code if you decide to change the implementation. Hence the type for member variable memory should probably be List rather than ArrayList.
Note that ArrayList may waste memory if the list of "note"s is large. I suggest using LinkedList instead. Alternatively, use an array (rather than a List) and handle expanding the array when adding a "note" as well as reducing the array when removing a "note".
Having an infinite loop, i.e. while (true), which contains a single if-else where both the if block and the else block contain break statements, means that the loop will perform exactly one iteration. May as well remove the while loop – which means also removing the break statements.
Rather than writing the code that generates a timestamp repeatedly, you should adopt the DRY principle and extract that code into a separate method.
The file name should be a constant so as to minimize the amount of code changes you will need to do if you decide to change the file name.
By convention, text files have a filename extension of .txt whereas binary files have the .data extension.
Although you don't need to, I personally prefer to initialize class member variables in the constructor.
The below code is a SSCCE, hence I added a main method. More notes appear after the code.
package Methods;
import java.util.*;
import java.time.format.*;
import java.time.*;
import java.io.*;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
public class FileSys {
private static final String FILENAME = "notes.txt";
private static final String CREATE = "C";
private static final String DELETE = "D";
private static final String FIND = "F";
private static final String QUIT = "Q";
private static final String SHOW = "S";
private static final String UPDATE = "U";
Scanner reader;
List<String> memory;
public FileSys() throws IOException {
reader = new Scanner(System.in);
memory = new LinkedList<String>();
loadFile();
}
public void fileHandling() {
Path path = Paths.get(FILENAME);
try (BufferedWriter bw = Files.newBufferedWriter(path,
StandardOpenOption.CREATE,
StandardOpenOption.WRITE);
PrintWriter pw = new PrintWriter(bw)) {
for (String write : memory) {
pw.println(write);
}
}
catch (IOException e) {
e.printStackTrace();
}
}
public void createNote() {
String dateTime = getTimestamp();
System.out.println();
System.out.println("Enter a note");
System.out.print("> ");
String note = reader.nextLine();
memory.add(note + " / " + dateTime);
fileHandling();
System.out.println("Note is saved!");
}
public void searchNote() {
System.out.print("\nEnter note number: ");
try {
int search = reader.nextInt();
reader.nextLine();
System.out.println("\nSearch result:");
int index = memory.indexOf(memory.get(search - 1));
if (index != -1) {
System.out.println("[" + (index + 1) + "]" + " " + memory.get(search - 1));
}
else {
System.out.println("Note number-" + search + " is not found in the collection!");
}
}
catch (IndexOutOfBoundsException e) {
System.out.println("The note number you have entered is invalid!");
}
}
public void updateNote() {
String dateTime = getTimestamp(); // ZonedDateTime.now(ZoneId.systemDefault()).format(dateTimeObj);
System.out.print("\nEnter note number to change: ");
try {
int search = reader.nextInt();
int index = memory.indexOf(memory.get(search - 1));
String updateLine;
if (index != -1) {
System.out.println("\nCurrent note: ");
System.out.println("[" + (index + 1) + "]" + " " + memory.get(search - 1));
System.out.println("\nThe updated note will be: ");
System.out.print("> ");
reader.nextLine();
updateLine = reader.nextLine();
memory.set(index, updateLine + " /" + dateTime);
System.out.print("Note has been updated successfully!\n");
}
else {
System.out.println(search + " is not found in the collection!");
}
}
catch (IndexOutOfBoundsException e) {
System.out.println("The note number you have entered is invalid!");
}
fileHandling();
}
public void deleteNote() {
System.out.print("\nEnter note number to delete: ");
try {
int search = reader.nextInt();
reader.nextLine();
int index = memory.indexOf(memory.get(search - 1));
System.out.println();
if (index != -1) {
System.out.println("[" + (index + 1) + "]" + " " + memory.get(search - 1));
System.out.print("\nDo you want to delete this note? \n[y] or [n]: ");
char delDecision = reader.nextLine().charAt(0);
if (delDecision == 'y' || delDecision == 'Y') {
memory.remove(index);
System.out.println("Note has been deleted successfully!");
System.out.println();
}
else if (delDecision == 'n' || delDecision == 'N') {
System.out.println("Note was not deleted!");
}
else {
System.out.println("Invalid input!");
}
}
else {
System.out.println(search + " is not found in the collection!");
}
}
catch (IndexOutOfBoundsException e) {
System.out.println("The note number you have entered is invalid!");
}
fileHandling();
}
public void displayNote() {
if (memory.size() > 0) {
int counter = 0;
for (String note : memory) {
System.out.printf("%d. %s%n", ++counter, note);
}
}
else {
System.out.println("There are no notes.");
}
}
private String getTimestamp() {
LocalDate todayDate = LocalDate.now();
LocalTime nowTime = LocalTime.now();
String timeFormat = nowTime.format(DateTimeFormatter.ofLocalizedTime(FormatStyle.MEDIUM));
String dateTime = todayDate.toString() + " at " + timeFormat;// ZonedDateTime.now(ZoneId.systemDefault()).format(dateTimeObj);
return dateTime;
}
private void loadFile() throws IOException {
Path path = Paths.get(FILENAME);
if (Files.isRegularFile(path)) {
memory.addAll(Files.readAllLines(path, Charset.defaultCharset()));
}
}
private void showMenu() {
String choice = "";
while (!QUIT.equalsIgnoreCase(choice)) {
System.out.println(CREATE + " - Create note");
System.out.println(DELETE + " - Delete note");
System.out.println(FIND + " - Search notes");
System.out.println(SHOW + " - Show notes");
System.out.println(UPDATE + " - Update note");
System.out.println(QUIT + " - Quit");
System.out.println();
System.out.print("Your choice: ");
choice = reader.nextLine();
if (!choice.isEmpty()) {
choice = choice.substring(0, 1);
choice = choice.toUpperCase();
switch (choice) {
case CREATE -> createNote();
case DELETE -> deleteNote();
case FIND -> searchNote();
case SHOW -> displayNote();
case UPDATE -> updateNote();
case QUIT -> System.out.println("Good bye.");
default -> System.out.println("Invalid: " + choice);
}
}
else {
System.out.println("No selection entered. Retry.");
}
}
}
public static void main(String[] args) {
try {
FileSys fs = new FileSys();
fs.showMenu();
}
catch (IOException xIo) {
xIo.printStackTrace();
}
}
}
Your code does not initially load memory with contents of file notes.txt so I added that in the constructor. Consequently you don't need to append to the file since you simply overwrite it with contents of memory.
The file handling is done using NIO.2 including try-with-resources – which was added in Java 7. There are more NIO.2 examples in the JDK documentation.
Whenever the code throws an unexpected exception, it is nearly always a good idea to print the stack trace.

Java programming project

I am in the middle of a university project, the task being to use a scanner to read the appropriate data of several data files. The project involves a superclass and several subclasses. So far the method below works perfectly and reads data corresponding to a class called Tool and all its fields. However I have recently added a subclass ElectricTool which extends class Tool and also which has introduced two new fields which need reading in the same way as before but within the same method shown below. I have tried a number of things but I can't seem to figure it out. Any suggestions? Preferably as clean/simple code as possible, I think it needs to be a read statement but I am struggling. The method is below:
public void readToolData()
{
Frame myFrame = null;
FileDialog fileBox = new FileDialog(myFrame,"Open", FileDialog.LOAD);
fileBox.setVisible(true);
String directoryPath = fileBox.getDirectory();
String fileName = fileBox.getFile();
File dataFile = new File(fileName);
System.out.println(fileName +" "+ directoryPath);
Scanner scanner = null;
try
{
scanner = new Scanner(dataFile);
}
catch (FileNotFoundException e)
{
System.out.println(e);
}
while( scanner.hasNextLine() )
{
String lineOfText = scanner.nextLine().trim().replaceAll("\\s+","");
if(!lineOfText.isEmpty() && !lineOfText.matches("^//.*") && !lineOfText.substring(0,1).equals("["))
{
System.out.println(lineOfText);
}
else{
continue;
}
Scanner scanner2 = new Scanner(lineOfText).useDelimiter("\\s*,\\s*");
while(scanner2.hasNext())
{
Tool tool = new Tool();
tool.readData(scanner2);
storeToolList(tool);
}
}
scanner.close();
}
electric tool class
tool class
data file
public void readToolData() {
Frame myFrame = null
FileDialog fileBox = new FileDialog(myFrame, "Open", FileDialog.LOAD);
fileBox.setVisible(true);
String directoryPath = fileBox.getDirectory();
String fileName = fileBox.getFile();
File dataFile = new File(directoryPath + fileName);
System.out.println(fileName + " " + directoryPath);
Scanner scanner = null;
try {
scanner = new Scanner(dataFile);
} catch (FileNotFoundException e) {
System.out.println(e);
}
// Current tool type
String toolType = null;
while( scanner.hasNextLine() ) {
String lineOfText = scanner.nextLine().trim();
// Skip empty lines and commentaries
if(lineOfText.isEmpty() || lineOfText.startsWith("//")) {
continue;
}
if (lineOfText.startsWith("[")) {
// Extract the tool type name
String withoutBracket = lineOfText.substring(1);
// Split by spaces and take the first word
String[] words = withoutBracket.split(" ");
toolType = words[0];
System.out.println("Reading information about " + toolType);
continue;
}
System.out.println(lineOfText);
Scanner scanner2 = new Scanner(lineOfText).useDelimiter("\\s*,\\s*");
Tool tool = null;
if ("ElectricTool".equals(toolType)) {
tool = new ElectricTool();
}
// In the future here will come more cases for different types, e.g.:
// else if ("HandTool".equals(toolType)) {
// tool = new HandTool();
// }
if (tool != null) {
tool.readData(scanner2);
storeToolList(tool);
}
}
scanner.close();
}
Remove scanner.skip line in Tool.readData:
public class Tool {
public void readData(Scanner scanner) {
toolName = scanner.next();
itemCode = scanner.next();
timesBorrowed = scanner.nextInt();
onLoan = scanner.nextBoolean();
cost = scanner.nextInt();
weight = scanner.nextInt();
scanner.skip(".*"); // Remove this line
}
}
And implement readTool method in ElectricTool:
#Override
public void readData(Scanner scanner) {
super.readData(scanner);
rechargeable = scanner.nextBoolean();
power = scanner.next(); // Or nextInt? what is the type of power field?
}
To print the information about the tools you should use polymorphism.
Modify your printAllTools method in Shop.java like this:
public void printAllTools() {
System.out.println("Information");
System.out.println("---------->");
for (Tool t : toolList) {
System.out.println("You have selected:\n");
t.printDetails();
}
}
Now, your method printDetails in Tool.java must be looking like this:
public void printDetails() {
System.out.println("Tool name: " + toolName + "\n" +
"Item code: " + itemCode + "\n" +
"Times borrowed: " + timesBorrowed + "\n" +
"On load: " + onLoan + "\n" +
"Cost: " + cost + "\n" +
"Weight: " + weight + "g\n"
);
}
and in the ElectricTool.java:
public void printDetails() {
super.printDetails();
System.out.println("Rechargeable: " + rechargeable + "\n" +
"Power: " + power + "\n"
);
}

How would I change this code to make it so that it asks me the location of the file that I want to load?

So my code currently has the user specify the name of the file that they want to load within the code itself but how would I make it so that when the program is run then the user will enter the location of the file that they want to load?
import java.io.*;
import java.util.*;
public class reader {
static int validresults = 0;
static int invalidresults = 0;
//used to count the number of invalid and valid matches
public static boolean verifyFormat(String[] words) {
boolean valid = true;
if (words.length != 4) {
valid = false;
} else if (words[0].isEmpty() || words[0].matches("\\s+")) {
valid = false;
} else if ( words[1].isEmpty() || words[1].matches("\\s+")) {
valid = false;
}
return valid && isInteger(words[2]) && isInteger(words[3]);}
//checks to see that the number of items in the file are equal to the four needed and the last 2 are integers
//also checks to make sure that there are no results that are just whitespace
public static boolean isInteger( String input ) {
try {
Integer.parseInt( input );
return true;
}
catch( Exception e ) {
return false;
}
}
//checks to make sure that the data is an integer
public static void main(String[] args) throws FileNotFoundException {
String hteam;
String ateam;
int hscore;
int ascore;
int totgoals = 0;
Scanner s = new Scanner(new BufferedReader(
new FileReader("fbscores.txt"))).useDelimiter("\\s*:\\s*|\\s*\\n\\s*");
while (s.hasNext()) {
String line = s.nextLine();
String[] words = line.split("\\s*:\\s*");
//splits the file at colons
if(verifyFormat(words)) {
hteam = words[0]; // read the home team
ateam = words[1]; // read the away team
hscore = Integer.parseInt(words[2]); //read the home team score
totgoals = totgoals + hscore;
ascore = Integer.parseInt(words[3]); //read the away team score
totgoals = totgoals + ascore;
validresults = validresults + 1;
System.out.println(hteam + " " + "[" + hscore + "]" + " " + ateam + " " + "[" + ascore + "]");
//output the data from the file in the format requested
}
else{
invalidresults = invalidresults + 1;
}
}
System.out.println("Total number of goals scored was " + totgoals);
//displays the the total number of goals
System.out.println("Valid number of games is " + validresults);
System.out.println("Invalid number of games is " + invalidresults);
System.out.println("EOF");
}
}
One approach would be to use a main loop asking for a file name and quitting program execution when no input is given.
Therefore I'd refactor most code of your main method into another function e.g. processFile(String fileName).
Then your main only deals with user input
public static void main(String args[]){
Scanner sc = new Scanner(System.in);
while(true){ //keep running till we break
System.out.println("Enter filename or return blank line to quit");
String fileName = sc.nextLine();
if(fileName != null && !fileName.isEmpty()){
processFile(fileName)
}else{
break; //no user input => exit
}
}
System.out.println("bye");
}
private static processFile(String fileName){
String hteam;
String ateam;
int hscore;
int ascore;
int totgoals = 0;
Scanner s = new Scanner(new BufferedReader(
new FileReader(fileName))).useDelimiter("\\s*:\\s*|\\s*\\n\\s*");
while (s.hasNext()) {
… //rest of your original code
}

BabyNames how to return only one line

I have an assignment where the user is asked for baby name using a scanner. Then it reads through files names.txt and meanings.txt and returns the popularity of the name for each decade ranging from 1890 - 2010 then it prints out the meaning. Some names have multiple meanings and some are used in both genders. The assignment states to print only the first line where the name is found. I am having trouble only returning the first line in which the name is found. PLEASE HELP ME!
import java.io.*;
import java.util.*;
public class BabyNames4 {
public static void main(String[] args) throws FileNotFoundException {
printIntro();
Scanner console = new Scanner(System.in);
System.out.print("Name: ");
String searchWord = console.next();
Scanner fileScan = new Scanner(new File("names.txt"));
String dataLine = find(searchWord, fileScan);
if (dataLine.length() > 0) {
while (dataLine.length() > 0) {
printName(dataLine);
dataLine = find(searchWord, fileScan);
}
}
Scanner fileScan2 = new Scanner(new File("meanings.txt"));
String dataLine2 = find(searchWord, fileScan2);
if (dataLine2.length() > 0) {
while (dataLine2.length() > 0) {
printMeaning(dataLine2);
dataLine2 = find(searchWord, fileScan2);
}
}
}
public static void printIntro() {
System.out.println("This program allows you to search through the");
System.out.println("dada from the Social Security Administration");
System.out.println("to see how popular a particular name has been");
System.out.println("since 1890");
System.out.println();
}
public static String find(String searchWord, Scanner fileScan) {
while (fileScan.hasNextLine()) {
String dataLine = fileScan.nextLine();
String dataLineLC = dataLine.toLowerCase();
if (dataLineLC.contains(searchWord.toLowerCase())) {
return dataLine;
//} else { runs a continuous loop
//System.out.println(search" not found.");
}
}
return "";
}
public static void printName(String dataLine) {
Scanner lineScan = new Scanner(dataLine);
String name = lineScan.next();
String gender = lineScan.next();
String rank = "";
while (lineScan.hasNext()) {
rank += lineScan.next() + " ";
}
System.out.println(name + (" ") + gender + (" ") + rank);
}
public static void printMeaning(String dataLine2) {
Scanner lineScan2 = new Scanner(dataLine2);
String name2 = lineScan2.next();
String gender2 = lineScan2.next();
String language = lineScan2.next();
String meaning = "";
while (lineScan2.hasNext()) {
meaning += lineScan2.next() + " ";
}
System.out.println(name2 + (" ") + gender2 + (" ") + language + (" ") + meaning);
}
}
It looks like sushain hit it with his comment.
The loop:
while (dataLine2.length() > 0) {
printMeaning(dataLine2);
dataLine2 = find(searchWord, fileScan2);
}
could be changed to:
while (dataLine2.length() > 0) {
printMeaning(dataLine2);
break;
}
This way you do not find the second definition and do not print it.
In this loop, you don't need to find the next line, correct?
if (dataLine.length() > 0) {
while (dataLine.length() > 0) {
printName(dataLine);
dataLine = find(searchWord, fileScan); // remove this line
}
}
If you remove the next find to dataLine and remove the while blocks in both instances where you search the file, you won't need a break, and you'll only end up printing one instance.
Do this:
String dataLine = find(searchWord, fileScan);
if (dataLine.length() > 0) {
printName(dataLine);
}

OutOfBoundsException When Calling Return For A Method JAVA

i'll get straight to the chase. If a user wants to read another file they must type r in the menu, then they are thrown with a return readFile(); method which takes them to the top of the program and asks them the same question it did at the beggining when they first ran this program. Only issue is when you type R or Default it throws an OutOFBoundsException. BTW It is Reading a CSV file
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1000
at studentrecs.StudentRecs.in(StudentRecs.java:71)
at studentrecs.StudentRecs.readFile(StudentRecs.java:55)
at studentrecs.StudentRecs.menu(StudentRecs.java:97)
at studentrecs.StudentRecs.main(StudentRecs.java:33)
Java Result: 1
/
public static Boolean readFile(String filename) throws IOException { //Constructor for filename
try {
Scanner userInput = new Scanner(System.in);
System.out.println("Type R To Read a File or Type Default for the default file");
user = userInput.nextLine();
if (user.equalsIgnoreCase("r")) {
user = userInput.nextLine();
}
filename = user;
if (user.equalsIgnoreCase("default")) {
filename = "newreg2.csv";
}
Scanner input = new Scanner(new FileReader(filename));
while (input.hasNext()) {
in(input.nextLine());
numstu++;
}
input.close();
return true;
} catch (IOException e) {
System.err.println(e.getMessage());
}
return false;
}
public static void in(String reader) {
String splitter[];
splitter = reader.split(",");
stu[numstu] = new StuRec();
stu[numstu].studentID = splitter[0];
stu[numstu].lastName = splitter[1];
stu[numstu].firstName = splitter[2];
stu[numstu].phoneNumber = splitter[3];
stu[numstu].courseCode = splitter[4];
stu[numstu].periodNumber = Integer.parseInt(splitter[5]); // parseInt turns a string of digits into an integer
stu[numstu].mark = Integer.parseInt(splitter[6]);
}
public static boolean menu() throws IOException {
String choice;
Scanner userInput = new Scanner(System.in);
System.out.println("=============================================");
System.out.println("Type R To Read Another File");
System.out.println("Type L To Print all File Records");
System.out.println("Type AA To Print The Average Of All The Marks");
System.out.println("Type X To Exit The Program");
choice = userInput.nextLine();
double average = 0.0; // declare average
if (choice.equalsIgnoreCase("L")) {
for (int i = 0; i < numstu; i++) {
System.out.println(stu[i].lastName + ", " + stu[i].firstName + ", " + stu[i].studentID + ", " + stu[i].phoneNumber + ", " + stu[i].courseCode + ", " + stu[i].periodNumber + ", " + stu[i].mark);
}
}else if (choice.equalsIgnoreCase("R")){
return readFile(filename);
} else if (choice.equalsIgnoreCase("AA")) {
for (int i = 0; i < numstu; i++) {
average += stu[i].mark; // keep adding to average
}
}else if (choice.equalsIgnoreCase("X")) {
for (int i = 0; i < numstu; i++) {
System.exit(i);
}
}else if (choice.equalsIgnoreCase("AC")) {
} else {System.err.println("Unknown Key Try Again...");
}
// divide by zero protection
if ( choice.equalsIgnoreCase("AA") && numstu > 0 ) {
average = average/numstu; // compute the average. Always use the size in terms of a variable whenever possible.
System.out.println(average); // as noted below, if this is an integer value, < #of students computations will eval to 0.
}
else if (!choice.equalsIgnoreCase("AA") && numstu < 0) {
System.out.println("Oops! No Marks To Calculate! :(");
}
return menu();
}
}
It looks like EITHER you have initialised numstu to start at 1, OR you have more than 1000 lines in your file.
The effect of either of these errors would be that you eventually attempt to write data to entry 1000 of stu. But since you've initialised stu with 1000 entries, numbered from 0 to 999, this gives your error.
You should make sure that numstu is initially 0, not 1.
And next time you post a question, post ALL of your code, not just the parts where you think the error might be. It's very difficult for most people to find bugs in code that they can't see.

Categories

Resources