File not created by using File.createNewFile(); - java

im having a small problem with my properties files with a PrintWriter.
This is the code for the main file:
package org.goverment;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Tg {
public static final void main(String[] args) throws Exception {
cout("The Goverment - Create your own country!/");
cout("Press the number associated with your choice then press enter./");
cout("1. New Game/");
cout("2. Continue/");
cout("3. ExitGame/");
int c = Integer.parseInt(cin());
if(c == 1) {
cout("/");
cout("Country name: ");
String name = cin();
cout("\nIs this a soviet country? (y/n): ");
String soviet = cin();
boolean svt;
if(soviet.equalsIgnoreCase("y") || soviet.equalsIgnoreCase("yes"))
svt = true;
else if(soviet.equalsIgnoreCase("n") || soviet.equalsIgnoreCase("no"))
svt = false;
else
svt = false;
Game.setup(Game.cc(), name, svt);
} else if(c == 2)
System.exit(0); // Game.c();
else if(c == 3)
System.exit(0);
}
private static String cin() throws IOException {
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
return br.readLine();
}
public static final void cout(String s) {
if(s.endsWith("/") || s.equalsIgnoreCase("")) {
System.out.println(s.substring(0, s.length() - 1));
} else {
System.out.print(s);
}
}
}
And this is the Game class:
http://pastebin.com/bktg6nSc
This is the problem:
The file isint created...
i keep flushing and closing but nothing happens.
i keep looking at the application data but no thegoverment.properties is there.
So what should i do?
I really do need help, its for a school project and i must do it by 2 days.

The bug is in Game.cc(). The method never returns if the for loop executes as written, so even though your code looks like it calls Game.setup(), the JVM never actually gets to execute it.
The problem is that regardless of the value of done when the while loop finishes, done is always reset to false before the while loop begins again. Classic infinite loop, and completely unrelated to your IO.
I had the following start to Game.cc() when I found the bug. Note the output lines added to aid in debugging.
public static final List<String> cc() {
List<String> countryNames = new ArrayList<String>();
System.out.println("About to begin for loop in Game.cc()");
for (int i = 0; i < 48; i++) {
System.out.println("for loop iteration "+i);
boolean done = false;
while (!done) {
You need to declare flag variables such as "boolean done = false;" outside the loop. Write future code like this:
public static final List<String> cc() {
List<String> countryNames = new ArrayList<String>();
boolean done = false;
for (int i = 0; i < 48; i++) {
while (!done) {
I should note that thegovernment.properties was correctly created after the fix, though not where one would expect to find it, since you hard-coded to Windows structures and I did not adjust the address before testing on linux. I found thegoverment.properties in the top--level folder of my package.
I should also note that after the properties file is created, it doesn't get modified ever again by Game.setup(), such as when the player starts a new game. Check your logic and test thoroughly to ensure that it's behaving the way you expect.
Best of luck in your studies!

If adding
writer.flush();
before closing does not work, then, intead of
PrintWriter writer = new PrintWriter(fl);
...
do
BufferedWriter writer = new BufferedWriter(fl);
writer.write("###################");
writer.newLine();
...
writer.flush();
writer.close();
If this still does not work try to create the file where you are executing the program, so:
File fl = new File("thegoverment.properties");

Related

Block of code is not touched

I'm building a small application in Java, small game mechanics but nothing serious. I have a class which purpose is to fetch data from a file. But when I declare the two classes to read from it the program justs ignore everything and continues. As a result, when I try to access the respective lists it gives me null pointer exception. Code of the method that fetches data below:
public void getData(int l, player tmp, level le) {
String[] dataPlayer;
String[] dataLevel;
try {
//FileReader f = new FileReader(this.levelPath.concat(Integer.toString(l)));
File f = new File(this.levelPath.concat(Integer.toString(l)));
BufferedReader buff = new BufferedReader(new FileReader(f));
System.out.println("Reached");
boolean eof = false;
while (!eof) {
String b = buff.readLine();
if (b == null)
eof = true;
else {
if (b.contains("player")) {
dataPlayer = b.split("-");
for (int i = 0; i < dataPlayer.length; i++) {
if (i == 0)
continue;
items it = new items(dataPlayer[i]);
tmp.setInventory1(it);
}
}else if (b.contains("level")) {
dataLevel = b.split("-");
for (int i = 0; i < dataLevel.length; i++) {
if (i == 0)
continue;
items it = new items(dataLevel[i]);
le.setSpecific(it);
}
}
}
}
}catch (IOException i) {
i.getMessage();
}
}
File contents of the file "levelData1":
player-hat
player-flashlight
level-flower
level-rock
player-adz
The problem with this particular problem was the path, it needed the absolute like that /home/toomlg4u/IdeaProjects/javaProject/src/Data/levelData.
You're doing a lot of things inside that try/catch that may not throw an IOException. If you get any other exception, it's not going to be caught. Depending on what other exception handling you have in place, that may cause weird behavior. For debugging, you could catch all exceptions, and see if you're getting something else.
If you want to remain to your loop code then you can refactor your code to look like this one:
public void getData(int l, player tmp, level le) {
try (BufferedReader buff = new BufferedReader(new FileReader(new File(this.levelPath + l)))) {
String b;
while ((b = buff.readLine()) != null) {
if (b.contains("player")) {
String[] dataPlayer = b.split("-");
items it = new items(dataPlayer[1]); //because you know that you will have an array with only 2 elements
tmp.setInventory1(it);
}else if (b.contains("level")) {
String[] dataLevel = b.split("-");
items it = new items(dataLevel[1]); //because you know that you will have an array with only 2 elements
le.setSpecific(it);
}
}
}catch (IOException e) {
e.printStackTrace();
}
}
It is a little bit better than that you have, easier to debug and to read. I advice you to read about try with resources.
As a rule of thumb, each time when you open a stream you have to close it. When you don't open it yourself then don't close it.
This is how it should look like a decent program in Java:
private Stream<Items> asStreamOfItems(String line){
return Stream.of(line.split("-")).skip(1).map(Items::new);
}
public void parseFile(String pathToTheFile) throws IOException {
List<String> lines = Files.readAllLines(Paths.get(pathToTheFile));
List<Items> players = lines.stream().filter(line -> line.contains("player")).flatMap(this::asStreamOfItems).collect(Collectors.toList());
List<Items> levels = lines.stream().filter(line -> line.contains("level")).flatMap(this::asStreamOfItems).collect(Collectors.toList());
........
}
In this case all your weird errors will vanish.
After you edited the post I saw your file content. In this case the code should look like this one:
class Items {
private final String name;
public Items(String name) {
this.name = name;
}
public String getName() {
return name;
}
public static Items parse(String line) {
return new Items(line.split("-")[1]);
}
}
public void parseFile(String pathToTheFile) throws IOException {
List<String> lines = Files.readAllLines(Paths.get(pathToTheFile));
List<Items> players = lines.stream().filter(line -> line.contains("player")).map(Items::parse).collect(Collectors.toList());
List<Items> levels = lines.stream().filter(line -> line.contains("level")).map(Items::parse).collect(Collectors.toList());
..............
}
Btw, you broke a lot of Java and general programming rules like:
using continue is a bad practice. It should be used only in extreme cases because it makes the code difficult to read.
the class name in Java should be in the CamelCase notation
one method should have only one responsibility
DON'T mutate the object inside of a method (example: tmp.setInventory1(it);) very very very bad practice
when you work with streams use try with resource or try/catch/finally to close your stream after you finish the reading.
Before jumping to write code explore the JAVA IO SDK to look for better methods to read from files

Reading from csv files

This is a project i'm working on at college, everything seems good except in the game class which initializes the game. Here is a snippet
public class Game{
private Player player;
private World world;
private ArrayList<NonPlayableFighter> weakFoes;
private ArrayList<NonPlayableFighter> strongFoes;
private ArrayList<Attack> attacks;
private ArrayList<Dragon> dragons;
public Game() throws IOException{
player = new Player("");
world = new World();
weakFoes = new ArrayList<NonPlayableFighter>();
strongFoes = new ArrayList<NonPlayableFighter>();
attacks = new ArrayList<Attack>();
dragons = new ArrayList<Dragon>();
loadAttacks ("Database-Attacks_20309.csv");
loadFoes ("Database-Foes_20311.csv");
loadDragons ("Database-Dragons_20310.csv");
}
after that follows some getters and the 4 method i am supposed to implement.
These methods are loadCSV(String filePath),loadAttacks(String filePath),loadFoes(String filePath),loadDragons(String filePath)
I have created loadCSV(String filePath) such that it returns an ArrayList of String[] here:
private ArrayList<String[]> loadCSV(String filePath) throws IOException{
String currentLine = "";
ArrayList<String[]> result = new ArrayList<String[]>();
FileReader fileReader = new FileReader(filePath);
BufferedReader br = new BufferedReader(fileReader);
currentLine = br.readLine();
while (currentLine != null){
String[] split = currentLine.split(",");
result.add(split);
}
br.close();
return result;
}
Then i would like to load some attacks, foes, and dragons and inserting them in the appropriate ArrayList.
I applied loadAttacks(String filePath) here:
private void loadAttacks(String filePath) throws IOException{
ArrayList<String[]> allAttacks = loadCSV(filePath);
for(int i = 0; i < allAttacks.size(); i++){
String[] current = allAttacks.get(i);
Attack temp = null;
switch(current[0]){
case "SA": temp = new SuperAttack(current[1],
Integer.parseInt(current[2]));
break;
case "UA": temp = new UltimateAttack(current[1],
Integer.parseInt(current[2]));
break;
case "MC": temp = new MaximumCharge();
break;
case "SS": temp = new SuperSaiyan();
break;
}
attacks.add(temp);
}
}
I wrote it such that it takes the ArrayList returned from loadCSV(String filePath) and searches in each String[] within the ArrayList on the first String using a switch thus creating the appropriate attack and adding it to attacks.
Then i would like to read another CSV for the Foes and the CSV file is structured such that in the first line there are some attributes the second line some attacks of type SuperAttack and the third line holds some attacks of type Ultimate attack. Also within each foe there is a boolean attribute that determines if it is a Strong or Weak Foe thus putting it in the right Arraylist. Here is the code for loadFoes(String filePath):
private void loadFoes(String filePath) throws IOException{
ArrayList<String[]> allFoes = loadCSV(filePath);
for(int i = 0; i < allFoes.size(); i += 3){
String[] current = allFoes.get(i);
String[] supers = allFoes.get(i+1);
String[] ultimates = allFoes.get(i+2);
ArrayList<SuperAttack> superAttacks = new ArrayList<SuperAttack>();
ArrayList<UltimateAttack> ultimateAttacks = new ArrayList<UltimateAttack>();
NonPlayableFighter temp = null;
for(int j = 0; i < supers.length; j++){
int index = attacks.indexOf(supers[j]);
if(index != -1){
superAttacks.add((SuperAttack)attacks.get(index));
}
else break;
}
for(int j = 0; i < ultimates.length; j++){
int index = attacks.indexOf(ultimates[j]);
if(index != -1){
ultimateAttacks.add((UltimateAttack)attacks.get(index));
}
else break;
}
if(current[7].equalsIgnoreCase("True")){
temp = new NonPlayableFighter(current[0], Integer.parseInt(current[1]),
Integer.parseInt(current[2]), Integer.parseInt(current[3]),
Integer.parseInt(current[4]), Integer.parseInt(current[5]),
Integer.parseInt(current[6]), true, superAttacks, ultimateAttacks);
strongFoes.add(temp);
}
else{
temp = new NonPlayableFighter(current[0], Integer.parseInt(current[1]),
Integer.parseInt(current[2]), Integer.parseInt(current[3]),
Integer.parseInt(current[4]), Integer.parseInt(current[5]),
Integer.parseInt(current[6]), false, superAttacks, ultimateAttacks);
weakFoes.add(temp);
}
}
}
First i get the first three String[] in the ArrayList returned from loadCSV(String filePath and made 2 loops to check if the attacks are within the previously loaded attacks CSV then i check for the attribute that determines if it is a strong or weak and accordingly creating a new NonPlayableFighter and adding it to the appropriate list.
Running the jUnit4 tests for this assignment it gives me a Compilation Error: Unhandled exception type IOException. And generally speaking does the code have any notable problems ?
It's better to reuse already exist CSV file readers for Java (e.g. CVSReader) if isn't a part of you task.
That makes a lot of code. I'll answer to your Compilation Error.
While reading a file you have to pu your code in a try catch in order to avoid this kind of error. In your loadCSV method you have to set up a try catch block.
Please refer to this site for complete tutorial.
try (BufferedReader br = new BufferedReader(new FileReader("C:\\testing.txt")))
{
String sCurrentLine;
while ((sCurrentLine = br.readLine()) != null) {
String[] split = currentLine.split(",");
result.add(split);
}
} catch (IOException e) {
e.printStackTrace();
}
To make it short, code that access to files have to be in a try catch to avoid IO Exception, or be in a method that throws the exception (but then it has to be catched elsewhere).
In that code you have a good example of a try-with-resource, very good way to manage your ressource and memory.
loadCSV(String filePath) is a infinite loop isn't it? And as for the IOException it as #RPresle suggested a try/catch would do the trick around the BufferedReader.

Issue checking a .txt file for an element using a while() loop

I'm writing a program that asks a user to log in and checks if their ID is inside a file "Employees.txt" and if it is then it will print out VALID __ ID if they're a Manager or an Assistant. But when I enter an invalid ID, say "x" in and then try again, it loops forever, not checking if the ID is valid. How can I fix this issue? I have Employees.txt in the same directory as Account.java and
E12,Manager
E13,Assistant
is what's inside the file. Any help would be appreciated as I've tried everything I could. Thanks.
import java.io.*;
import java.util.*;
public class Account
{
public static String accountInput;
public static boolean inSystem = true;
public static boolean displayLogIn = true;
public static boolean managerLogIn = false;
public static Scanner userInput = new Scanner(System.in);
public static File stockFile = new File("Stock.txt");
public static File employeesFile = new File("Employees.txt");
public static File transactionsFile = new File("Transactions.txt");
public static void main(String[] args) throws IOException
{
String[] contents;
System.out.println("\tWorking Files");
System.out.println("-------------------------------------------");
System.out.println("Stock File:\t\tStock.txt\nEmployee File:\t\tEmployees.txt\nTransactions File:\tTransactions.txt\n\n");
Scanner readEmployeesFile = new Scanner(employeesFile);
while(inSystem)
{
while(displayLogIn)
{
System.out.print("Enter Employee ID(i.e E1)\tEnter Q to Quit Program.\nEnter here: ");
accountInput = userInput.nextLine();
while(readEmployeesFile.hasNextLine())
{
contents = readEmployeesFile.nextLine().split(",");
if(contents[0].equals(accountInput) & contents[1].equals("Manager"))
{
displayLogIn = false;
System.out.print("Valid MGR ID");
inSystem = false;
}
else if(contents[0].equals(accountInput) & contents[1].equals("Assistant"))
{
displayLogIn = false;
System.out.print("Valid AST ID");
inSystem = false;
}
else if(accountInput.equals("Q"))
{
displayLogIn = false;
inSystem = false;
}
}
}
}
}
}
When you enter an ID, you start looping on your file to see if that ID matches.
You reach the end of the file. readEmployeesFile.hasNextLine() is false. So you iterate again, read the next ID.
But the readEmployeesFile is still at the end of the file. There is nothing that takes it back to the beginning. So when it gets to the while again, readEmployeesFile.hasNextLine() is still false.
Possible solutions:
Open the scanner, readEmployeesFile, not at the beginning of the method, but right before you use it. Then close it right after you reach the end of the file. So you will be opening and closing it every time the user enters an ID.
Read all the IDs from the file into a Map before you start prompting the user, and then look for the ID in that map instead of directly in the file. This would be more efficient.
The problem is that you open the Scanner inside the loop, forcing it to read all the contents of the file on the first iteration. This means that the condition in while(readEmployeesFile.hasNextLine()) will always evaluate to false after the first iteration and the loop will never be entered again. For this reason only the first trial may be valid, afterwards your loop cannot terminate.
Here is adjusted code that worked for me:
import java.io.*;
import java.util.*;
public class Account
{
public static String accountInput;
public static boolean inSystem = true;
public static boolean displayLogIn = true;
public static Scanner userInput = new Scanner(System.in);
public static File employeesFile = new File("Employees.txt");
public static void main(String[] args) throws IOException
{
List<String[]> contents = new ArrayList<>();
System.out.println("\tWorking Files");
System.out.println("-------------------------------------------");
System.out.println("Stock File:\t\tStock.txt\nEmployee File:\t\tEmployees.txt\nTransactions File:\tTransactions.txt\n\n");
Scanner readEmployeesFile = new Scanner(employeesFile);
while(readEmployeesFile.hasNextLine()) {
String[] current = readEmployeesFile.nextLine().split(",");
contents.add(current);
}
while(inSystem)
{
while(displayLogIn)
{
System.out.print("Enter Employee ID(i.e E1)\tEnter Q to Quit Program.\nEnter here: ");
accountInput = userInput.nextLine();
for(String[] content: contents) {
if (content[0].equals(accountInput) & content[1].equals("Manager")) {
displayLogIn = false;
System.out.print("Valid MGR ID");
inSystem = false;
} else if (content[0].equals(accountInput) & content[1].equals("Assistant")) {
displayLogIn = false;
System.out.print("Valid AST ID");
inSystem = false;
} else if (accountInput.equals("Q")) {
displayLogIn = false;
inSystem = false;
}
}
}
}
readEmployeesFile.close();
}
}
As you can see, the input file is read a single time before entering the loop and stores all the lines in contents which is now of type List<String[]>. In the for loop you simply need to check the contents of the file that have already been read.
On a side note, you should always close the resources that you are using. In this case I refer to the Scanner object and this is why I included the line readEmployeesFile.close(); after your loop.
Change
contents[0].equals(accountInput) & contents[1].equals("Manager")
contents[0].equals(accountInput) & contents[1].equals("Assistant")
to
contents[0].equals(accountInput) && contents[1].equals("Manager")
contents[0].equals(accountInput) && contents[1].equals("Assistant")
The AND operator is represented with a double ampersand (&&), not one.

Basic Java IO, always throwing exception

I'm new to Java and am trying to write a program that has one argument, the path of a text file. The program will locate the text file and print it out to the screen. Eventually I'm going to build this to format the given text file and then print it out to an outfile, but I'll get there later.
Anyways my program is always throwing and IOException and I'm not sure why. Given the argument C:\JavaUtility\input.txt , I receieve "Error, could not read file" during runtime. My code is located below.
import java.io.*;
public class utility {
public static void main(String[] path){
try{
FileReader fr = new FileReader(path[0]);
BufferedReader textReader = new BufferedReader(fr);
String aLine;
int numberOfLines = 0;
while ((aLine = textReader.readLine()) != null) {
numberOfLines++;
}
String[] textData = new String[numberOfLines];
for (int i=0;i < numberOfLines; i++){
textData[i] = textReader.readLine();
}
System.out.println(textData);
return;
}
catch(IOException e){
System.out.println("Error, could not read file");
}
}
}
[EDIT] Thanks for all the help everyone! So given my end goal, I thought it would still be useful to find the number of lines and store in a finite array. So I ended up writing two classes. The first, ReadFile.java found the data I wanted and handles most of the reading. The second FileData.java invokes the methods in ReadFile and prints out. I've posted them below incase someone later finds them useful.
package textfiles;
import java.io.*;
public class ReadFile {
private String path;
public ReadFile(String file_path){
path = file_path;
}
int readLines() throws IOException{
FileReader file_to_read = new FileReader(path);
BufferedReader bf = new BufferedReader(file_to_read);
String aLine;
int numberOfLines = 0;
while ((aLine = bf.readLine()) != null){
numberOfLines++;
}
bf.close();
return numberOfLines;
}
public String[] OpenFile() throws IOException{
FileReader fr = new FileReader(path);
BufferedReader textReader = new BufferedReader(fr);
int numberOfLines = readLines();
String[] textData = new String[numberOfLines];
for(int i=0; i < numberOfLines; i++){
textData[i] = textReader.readLine();
}
textReader.close();
return textData;
}
}
package textfiles;
import java.io.IOException;
public class FileData {
public static void main(String[] args)throws IOException{
String file_name = args[0];
try{
ReadFile file = new ReadFile(file_name);
String[] aryLines = file.OpenFile();
for(int i=0; i < aryLines.length; i++){
System.out.println(aryLines[i]);
}
}
catch (IOException e){
System.out.println(e.getMessage());
}
}
}
You're at the end of the file. When you determine the number of lines in the file, you've read until the end of the file,and the EOF Flag is set. [Edit: As #EJP notes below, BufferedReader returns null reading past the end of a file. The fact your reader isn't where you want it, however, remains true.] In the past, I've hacked around this simply by closing and re-opening the file. Alternatively, look into Array Lists or simple Lists. They're dynamically re-sizing, so you don't need to know the number of lines in the file ahead of time.
As mentioned by #mikeTheLiar you are at End Of File. BufferedReader reference is File Handler with an internal cursor pointing to current position in file. As you fire readLine() method, the pointer reads characters till it reaches new line character, returning the string. The pointer is set to new position. Once you read all the lines then readLine() returns null. After that if you call readLine() it will throw IOException. As noted by #EJP
One of the best coding rules while using IO API is to always check for EOF condition - the way you have in first loop. Once you reach EOF after that you should not call read method on the same reference without resetting the cursor - this can be done by calling reset() method.
IMHO, in your case there is no need for second loop. You can achieve the functionalty using one loop only.
import java.io.*;
import java.util.ArrayList;
public class utility {
public static void main(String[] path){
try{
FileReader fr = new FileReader(path[0]);
BufferedReader textReader = new BufferedReader(fr);
String aLine;
int numberOfLines = 0;
ArrayList readLines = new ArrayList();
while ((aLine = textReader.readLine()) != null) {
numberOfLines++;
readLines.add(aLine);
}
//Assuming you need array of lines, if not then you can print the lines directly in above loop
String[] textData = readLines.toArray();
System.out.println(textData);
return;
}
catch(IOException e){
System.out.println("Error, could not read file");
}
}
}
EDIT
I tried your code - it is working fine and printing the array reference. As suggested in comments the problem is with source (file might not be readable due to security or any other reason) - if you can print the exception message and get the exact line number where exception is thrown it would be helpful.
Couple of observations apart from the IO exception:
You are trying to open the file twice. readLines() method is called from within OpenFile(). Following the sequence of code file is first opened in OpenFile() when you create textReader. After that you are calling readLines() which is again trying to open the file when you create file_to_read.
You should try to avoid that and in your flow you should call int numberOfLines = readLines(); before FileReader fr = new FileReader(path);
Again IMHO there should be only one method and you should iterate over the file only once - both from efficience/performance and code maintainability perspective. You can change your ReadFile class as follows:
package textfiles;
import java.io.*;
import java.util.ArrayList;
public class ReadFile {
private String path;
public ReadFile(String file_path){
path = file_path;
}
//You need not have separate file for counting lines in file
//Java provides dynamic sized arrays using ArrayList
//There is no need to count lines
public String[] OpenFile() throws IOException{
FileReader fr = new FileReader(path);
BufferedReader textReader = new BufferedReader(fr);
ArrayList fileLines = new ArrayList();
String readLine = textReader.readLine();
while(readLine != null){
fileLines.add(readLine);
readLine = textReader.readLine();
}
textReader.close();
return fileLines.toArray();
}
}
Another small observation: in some places the java variable naming conventions are not followed. OpenFile() method should be openFile() and file_to_read should be fileToRead
Contrary to several answers here, readLine() does not throw an exception at end of file, it just keeps returning null. Your problem is being masked by another one. Never just make up your own error messages. Always print the one that comes with the exception. If you had done that you would probably have found the problem immediately. Almost certainly you weren't able to open the file at all, either because it wasn't there or you didn't have read access. The exception will tell you.

Trying to stop a loop from infinitely looping, but also keep it from "break"ing every run

I have a loop that reads the number of lines in a text file when the program starts, and then depending on the amount of lines, it stores that many objects into a new (Vehicle[]) array (Maximum 4).
public boolean addVehicle(Vehicle[] Honda) throws FileNotFoundException
{
Scanner reader = new Scanner(file);
String strLine = "";
if(canAddVehicle() == true)
{
for(int i = 0; i < vehicles.length;i++)
{
System.out.println("This file is: " + file);
int counter = 0;
if(vehicles[i] == null)
{
try{
// Open the file that is the first
// command line parameter
FileInputStream fstream = new FileInputStream(this.file);
// Get the object of DataInputStream
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
//Read File Line By Line
while ((strLine = br.readLine()) != null) {
//Declare objects inside the array.
Honda[counter] = new Vehicle();
Honda[counter].readRecord(reader);
vehicles[counter] = Honda[counter];
counter++;
}
strLine = "";
//Close the input stream and scanner
reader.close();
in.close();
}catch (Exception e){//Catch exception if any
System.err.println("Error: " + e.getMessage());
}
}
break;
}
}
return true;
}
The part I'm having trouble with is this line:
if(vehicles[i] == null)
After the program starts, users can choose to add new Vehicles to the array. If you go through the code line by line, you can see that it starts of at i = 0, and let's say when the program first ran it found 2 lines of values, so it stored 2 objects into the array.
Values 0 and 1 are taken. That means when the user goes to add a new Vehicle, it will skip over if(vehicles[i] == null), because spot [0] is not null, it contains the values from the beginning of the program.
It then leads to the break; and kicks you out of the method without going back through the for loop to check if there are any other null values in the array.
What could I possibly do here?
two things,
a. switch break to continue, and place break in the right place that you want it.
b. you should close your file stream if your finish using it because when u open a fStream it
"holds the file open" and un useable until you close the fStream
If you format your source it will be easier to see where your break is currently located. Then try to think about how you would manually step through your program. That usually helps me. The you can decide if you want to break always in your loop or only if you just loaded the new vehicles.
Peter Lawrey gave a good comment to use a debugger, after figuring what you ant your program to do, if it does not behave as you expected, using a debugger (very easy in most IDEs) you can step through your program to see each action it takes and check the values of your variables at each step.
Your code really makes little sense. From what I understand of your problem description the code below might or might not be what you want to do:
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
public class VehicleList {
public class Vehicle {
private final String brand;
private final String make;
private final String year;
public Vehicle(String[] args) {
if (args.length < 3) {
throw new IllegalArgumentException("Too few args: " + args.length);
}
this.brand = args[0];
this.make = args[1];
this.year = args[2];
}
#Override
public String toString() {
return String.format("%s %s %s", year, brand, make);
}
}
public List<Vehicle> readVehicles(String fileName) throws IOException {
List<Vehicle> vehicles = new ArrayList<Vehicle>();
System.out.println(String.format("Reading vehicles from %s:", fileName));
readVehicles(vehicles, new Scanner(new File(fileName)), false);
System.out.println(String.format("Reading vehicles from user:"));
readVehicles(vehicles, new Scanner(System.in), true);
return vehicles;
}
private void readVehicles(List<Vehicle> vehicles, Scanner scanner, boolean skipLineCheck) {
int count = 0;
while (skipLineCheck || scanner.hasNextLine()) {
String[] tokens = scanner.nextLine().split("\\s+");
if (tokens.length < 3) {
break;
}
vehicles.add(new Vehicle(tokens));
count++;
}
scanner.close();
System.out.println(String.format("Read %s vehicles", count));
}
public static void main(String[] args) throws IOException {
VehicleList instance = new VehicleList();
List<Vehicle> vehicles = instance.readVehicles("vehicles.txt");
System.out.println("Read the following vehicles:");
System.out.println(Arrays.toString(vehicles.toArray()));
}
}
The boolean skipLineCheck is needed to stop the scanner from reading past the last line in the file and throwing a NoSuchElementException. For user input we don't want to do this check, because it forces the user to give an extra RETURN to end the input.
To run this you need to create a file called "vehicles.txt" in your working directory with for example the following contents:
Volvo Station 2008
Audi A4 2009
Honda Civic 2009
Toyota Prius 2008
A test run gives output like below:
Reading vehicles from vehicles.txt
Read 4 vehicles
Reading vehicles from user
Nissan Micra 2002
BMW cabriolet 1996
Read 2 vehicles
Read the following vehicles:
[2008 Volvo Station, 2009 Audi A4, 2009 Honda Civic, 2008 Toyota Prius, 2002 Nissan Micra, 1996 BMW cabriolet]
Why have you got the break there at all - it's just going to make it do exactly what you describe. Remove it and all will be well.
Based off of this statement: It then leads to the break; and kicks you out of the method without going back through the for loop to check if there are any other null values in the array.
it sounds like you want a continue where the break is.
break will cause the for loop to break, while continue will cause the code in the loop to be read (from top to bottom) with i incremented by 1 (in this case)
Thanks for the answers everyone. I was programming for around 12 hours and my mind was just dead when I asked the question. Not sure what I was doing. I've completed my code with this:
public boolean addVehicle(Vehicle[] Honda) throws FileNotFoundException
{
boolean found = false;
int position = 0;
if(canAddVehicle() == true)
{
for(int i = 0; i < vehicles.length && !found; i++)
{
if(vehicles[i] == null)
{
position = i;
found = true;
}
}
Scanner reader = new Scanner(file);
while(reader.hasNext())
{
Honda[position] = new Vehicle();
Honda[position].readRecord(reader);
vehicles[position] = Honda[position];
position++;
}
reader.close();
return true;
}
return false;
}

Categories