I am able to read a file using a Scanner. When the return type is void, I am able to read and print the data to the console, however, immediately afterward it throws an ArrayOutOfBoundsException. Ideally, I want to return as a string array, however, I only get an ArrayOutOfBoundsException. In both cases, the exception is thrown at the line cancers[j] = input.nextLine(). I have already made sure the size of the array is correct. When I do not hardcode the size of it, then the compiler throws a NullPointerException at the same line (which makes sense since the size of the array is not declared).
I need the method to return a string array as I have to do additional manipulations to it.
public String[] readCancer() {
cancers = new String[21];
int j = 0;
try {
input = new Scanner(myData);
String result;
while(input.hasNext()) {
++j;
cancers[j] = input.nextLine();
//System.out.println(cancers[j]);
}
} catch (FileNotFoundException fnfx) {
JOptionPane.showMessageDialog(null, "Txt file could not be found");
}
return cancers;
}
I tried re-writing the method in a slightly different way but I get the same error, only this time it is at output[i] = result;
public String[] readCancers() {
FileInputStream fis;
DataInputStream dis;
BufferedReader br;
InputStreamReader isr;
String result;
String[] output = new String[21];
int i = 0;
try {
fis = new FileInputStream(myData);
dis = new DataInputStream(fis);
isr = new InputStreamReader(dis);
br = new BufferedReader(isr);
while((result = br.readLine()) != null) {
++i;
output[i] = result;
}
} catch (FileNotFoundException fnfx) {
fnfx.printStackTrace();
} catch (IOException iox) {
iox.printStackTrace();
}
return output;
}
It's hard to know how many elements your file has but I'm assuming you have 21 elements and so you need a 21 element array. You've declared an array of 21 elements but the following code:
++j;
Means the following:
j = j+1;
And then you add an element to your array using j which results in you skipping j = 0 completely and the 21st item tries to get placed at the 22nd element of the array, which is out of bounds. What you might want is something like this:
cancers[j];
j++;
Or:
cancers[j++];
That way you're not going to go out of bounds. If you have more than 21 items then I'd suggest you increase the array size.
As the commenters to your question: it can be an off-by-one type error, because you skipped the first array element. But once you have a fixed size array to read in, you'd have to bound check the value of i or j in the while loop in any case: while(input.hasNext() && j < 20) or while((result = br.readLine()) != null && i < 21).
Then after the loop check if there would be any extra input, that may indicate an error, you have to handle that.
Related
I'm trying to to read the file contents into a character array using the scanner class and I keep getting a string index out of bounds error from my code and I'm not sure what's wrong
File fileName = null;
if(0<args.length) {
fileName = new File(args[0]);
}
Scanner s = null;
try {
s = new Scanner(fileName);
s.useDelimiter(",");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
char[]array = new char[26];
while(s.hasNext()) {
for(int i=0; i<27; i++) {
array[i] = s.next().charAt(i);
}
}
As far as I can tell, your code is equivalent to the following, which has no out of bounds exceptions
char[]array;
while(s.hasNext()) {
array = s.next().toCharArray();
}
However, after that while loop, your array will only equal the very last scanned value.
If you have individual comma separated characters, you can use the following. You do not need a loop within the existing loop
char[]array = new char[26];
int i = 0;
while(s.hasNext()) {
array[i++] = s.next().charAt(0);
}
In any case, I suggest using StringTokenizer rather than a Scanner
In your for loop, you are trying to access a[26] but you have declared memory for 26 characters. So you can access only a[0] to a[25].
I need to read a text file into a 2D array, I can read files into the program perfectly fine (see my code below) however I cannot get my head around how to read them into a 2D array. The array the function is reading into is a global array hence why it's not in the function.
Also I won't know the amount of rows the array has at first (currently set at 300 as it won't be over this) and I know this could cause a problem, I've seen some people suggest using ArrayLists however I have to have a 2D array so I was also wondering if there was a way to change an ArrayList to a 2D array and if this would be more effective?
public static String readMaze(String fileName) {
String line = null;
try {
FileReader fileReader = new FileReader(fileName);
BufferedReader bufferedReader = new BufferedReader(fileReader);
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
for (int i = 0; i < mazeNew.length; i++) {
for (int j = 0; j < mazeNew[i].length; j++) {
// mazeNew[i][j] = ; - this is where I think something needs to be added
}
}
}
bufferedReader.close();
}
catch (FileNotFoundException ex) {
System.out.println("Unable to open file: " + fileName);
}
catch (IOException ex) {
System.out.println("Error reading file: " + fileName);
}
return fileName;
}
example text file:
11 4
5 6
4 6
0 5
3 5
8 7
1 4
There's a few options here, but generally you'll want to use the Java Scanner class as it's designed for exactly this kind of thing. Alternatively, use an existing structured data format (like JSON or XML) and an existing parser to go with it - the advantage being you can make use of a vast amount of tools and libraries which deal with those formats and don't have to re-invent anything.
However, following through with the scanner approach, it would be like so:
public static ArrayList<int[]> readMaze(String fileName) {
// Number of ints per line:
int width=2;
// This will be the output - a list of rows, each with 'width' entries:
ArrayList<int[]> results=new ArrayList<int[]>();
String line = null;
try {
FileReader fileReader = new FileReader(fileName);
BufferedReader bufferedReader = new BufferedReader(fileReader);
Scanner mazeRunner = new Scanner(bufferedReader);
// While we've got another line..
while (mazeRunner.hasNextLine()) {
// Setup current row:
int[] row = new int[width];
// For each number..
for (int i = 0; i < width; i++) {
// Read the number and add it to the current row:
row[i] = mazeRunner.nextInt();
}
// Add the row to the results:
results.add(row);
// Go to the next line (optional, but helps deal with erroneous input files):
if ( mazeRunner.hasNextLine() ) {
// Go to the next line:
mazeRunner.nextLine();
}
}
mazeRunner.close();
}
catch (FileNotFoundException ex) {
System.out.println("Unable to open file: " + fileName);
}
catch (IOException ex) {
System.out.println("Error reading file: " + fileName);
}
return results;
}
If you have fixed no. of columns you can use this, but make sure input file must follow the same no of coulmns.
FileReader fileReader = new FileReader(fileName);
Scanner sc = new Scanner(fileReader);
int row=0, col=0;
while ((sc.hasNext()) != null) {
if(col < colSize){ //colSize is size of column
mazeNew[row][col]= sc.nextInt();
}
else{
col=0;
row++;
}
}
Below is the core logic, you would probably also like to to handle some errors, such as how many elements is a line split into, are there empty lines, etc.
List<String[]> list = new ArrayList<>();
Pattern pattern = Pattern.compile("\\s+");
while ((line = bufferedReader.readLine()) != null) {
list.add(pattern.split(line, -1));
}
String[][] mazeNew = list.toArray(new String[0][0]);
Something like this would work
it wont only read 2d text files .. it should work fine with any dimensions
public class Utile{
public static ArrayList<int[]> readMaze(String path){
ArrayList<int[]> result = new ArrayList<>();
try{
Scanner sc = new Scanner(new File(path));
String[] temp;
String line;
while(sc.hasNextLine()){
line = sc.nextLine();
if (line.length() != 0){ //if the line is empty it will cause NumberFormatException
temp = line.split(" ");
int[] val = new int[temp.length];
for(int i = 0;i < temp.length;i++){
val[i] = Integer.pareseInt(temp[i]);
}
result.add(val);
}
}
sc.close();
}catch(Exception e){
e.printStackTrace(); //just log it for now
}
return result;
}
}
I am not a java expert, but in PHP I would do it with explode(). But I found an example how to do the same in java using string.split(). The result is the same ... an 2D Array of the content. If possible you should try to add an delimiter to the rows inside that text document. But you could split the rows on the space character either.
Example:
String foo = "This,that,other";
String[] split = foo.split(",");
StringBuilder sb = new StringBuilder();
for (int i = 0; i < split.length; i++) {
sb.append(split[i]);
if (i != split.length - 1) {
sb.append(" ");
}
}
String joined = sb.toString();
I'm having issues reading and storing only integers from a text file. I'm using a int array so I want to do this without list. I'm getting a input mismatch exception, and I don't know how I should go about correcting that issue. The text files being read from also include strings.
public static Integer[] readFileReturnIntegers(String filename) {
Integer[] array = new Integer[1000];
int i = 0;
//connect to the file
File file = new File(filename);
Scanner inputFile = null;
try {
inputFile = new Scanner(file);
}
//If file not found-error message
catch (FileNotFoundException Exception) {
System.out.println("File not found!");
}
//if connected, read file
if(inputFile != null){
System.out.print("number of integers in file \""
+ filename + "\" = \n");
//loop through file for integers and store in array
while (inputFile.hasNext()) {
array[i] = inputFile.nextInt();
i++;
}
inputFile.close();
}
return array;
}
You might use something like this (to skip over any non-int(s)), and you should close your Scanner!
// if connected, read file
if (inputFile != null) {
System.out.print("number of integers in file \""
+ filename + "\" = \n");
// loop through file for integers and store in array
try {
while (inputFile.hasNext()) {
if (inputFile.hasNextInt()) {
array[i] = inputFile.nextInt();
i++;
} else {
inputFile.next();
}
}
} finally {
inputFile.close();
}
// I think you wanted to print it.
System.out.println(i);
for (int v = 0; v < i; v++) {
System.out.printf("array[%d] = %d\n", v, array[v]);
}
}
Change hasNext() to hasNextInt() in your while loop.
What you need to do is before you get a new value and try to put it into the array you need to check to make sure that it is in fact an int and if it isn't then skip over it and move on to the next value. Alternately you could make a string array of all of the values and then copy only the integers into a separate array. However, the first solution is probably the better of the two.
Also... As has been mentioned in the comments it tends to be easier to read the integers in as strings and then parse the values from them...
*The following code builds a "2D" array from strings in a text file. At present it is returning a NullPointException error on the line:
temp = thisLine.split(delimiter);
My question is, am I correct in understanding that temp is returning null? If so, why, and how do I add a check for null? I'm rather new to Java, and this is my first attempt at creating a string array of arrays from a file.*
--------Edit--------
The above has been solved.
For those interested below is the code returning a IndexOutOfBoundsException. Specifically the line:
fileContents.set(i, fileContents.get(i).replace(hexLibrary[i][0], hexLibrary[i][1]));
System.out.println("SnR after this");
String[][] hexLibrary; // calls the replaces array from the LibToArray method
hexLibrary = LibToArray();
for(int i=0;i<502;i++){
{
fileContents.set(i, fileContents.get(i).replace(hexLibrary[i][0], hexLibrary[i][1]));
}
}
for (String row : fileContents) {
System.out.println(row); // print array to cmd
}
______________________________
public static String[][] LibToArray()
{
String thisLine;
String[] temp;
String delimiter=",";
String [][] hexLibrary = new String[502][2];
try
{
BufferedReader br= new BufferedReader(new FileReader("hexlibrary.txt"));
for (int j=0; j<502; j++) {
thisLine=br.readLine();
temp = thisLine.split(delimiter);
for (int i = 0; i < 2; i++) {
hexLibrary[j][i]=temp[i];
}
}
}
catch (IOException ex) { // E.H. for try
JOptionPane.showMessageDialog(null, "File not found. Check name and directory."); // error message
}
return hexLibrary;
}
It's more likely that thisLine is null. That will happen if you run out of input before 502 lines are read. If thisLine is not null, then thisLine.split(delimiter) will not return null. You should always check for a null line:
for (int j=0; j<502; j++) {
thisLine=br.readLine();
if (thisLine != null) {
temp = thisLine.split(delimiter);
for (int i = 0; i < 2; i++) {
hexLibrary[j][i]=temp[i];
}
} else {
// report error: premature end of input file
break; // no point in continuing to loop
}
}
Personally, I'd write your method to not assume any particular file length:
public static String[][] LibToArray() {
List<String[]> lines = new ArrayList<>();
String delimiter=",";
try (BufferedReader br= new BufferedReader(new FileReader("hexlibrary.txt"))) {
String line = br.readLine();
while (line != null) {
String[] tmp = line.split(delimiter);
// the next line is dangerous--what if there was only one token?
// should add a check that there were at least 2 elements.
lines.add(new String[] {tmp[0], tmp[1]});
line = br.readLine();
}
} catch (IOException ex) {
JOptionPane.showMessageDialog(null, "File not found. Check name and directory.");
}
String[][] hexLibrary = new String[lines.length][];
lines.toArray(hexLibrary);
return hexLibrary;
}
(The above uses the new Java 7 try-with-resources syntax. If you're using an earlier Java, you should add a finally clause that closes br before the method returns.
If the first line (or any line) of hexlibrary.txt is empty or is not delimited by ","s, the String array returned by split() will probably be null.
To check for that, just add an if-condition around your second for loop, something like this:
if (temp == null) { /* your loop here */ }
You are not checking for end of the stream while reading the file.
Method readLine returns a null if the reader reaches end of the stream. You are hitting this point (null) in the first for loop (before it exits), depending on number of lines in the text file.
I want to read lines of numbers from a file. The code is as follows but the IDE shows NullPointerException runtime exception. Not sure what I am doing wrong.
//reading the contents of the file into an array
public static void readAndStoreNumbers() {
//initialising the new object
arr = new int[15][];
try {
//create file reader
File f = new File("E:\\Eclipse Projects\\triangle.txt");
BufferedReader br = new BufferedReader(new FileReader(f));
//read from file
String nums;
int index = 0;
while ((nums = br.readLine()) != null) {
String[] numbers = nums.split(" ");
//store the numbers into 'arr' after converting into integers
for (int i = 0; i < arr[index].length; i++) {
arr[index][i] = Integer.parseInt(numbers[i]);
}
index++;
}
} catch (IOException e) {
e.printStackTrace();
}
}
Your second dimension of arr is uninitialized, and you are invoking
arr[index].length
You could be running into an NPEX for two reasons.
You don't finish your definition of arr - it's not evident in your code that you declare arr as int arr[][];
Even if you had the above, you wouldn't have set aside space for your second array. What you have now is a jagged array; you can have elements of whatever length in the second dimension you wish in your second array.
The only modification I made to your code to get it to work would be the following line:
arr[index] = new int[numbers.length];
...after pulling elements into numbers, and before entering the loop.
you need to change -
for(int i=0; i<arr[index].length; i++) {
to
arr[index] = new int[numbers.length];
for (int i = 0; i < numbers.length; i++) {
Java doesn't have real multidimensional arrays. What you are using is actually an array of int arrays: new int[n][] actually creates an array with room for n objects of type int[].
Consequently you will have to initialize each of those int arrays separately. That would have been obvious from the fact that you never actually specified the length of the second dimension anywhere in your program.
I think you should use StringBuilder..
//reading the contents of the file into an array
public static void readAndStoreNumbers() {
//initialising the StringBuffer
StringBuilder sb = new StringBuilder();
try {
//create file reader
File f = new File("E:\\Eclipse Projects\\triangle.txt");
BufferedReader br = new BufferedReader(new FileReader(f));
//read from file
String nums;
int index = 0;
while ((nums = br.readLine()) != null) {
String[] numbers = nums.split(" ");
//store the numbers into 'arr' after converting into integers
for (int i = 0; i < arr[index].length; i++) {
sb.append(Integer.parseInt(numbers[i])).append("\n");
}
}
} catch (IOException e) {
e.printStackTrace();
}
}