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].
Related
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 cannot for the life of me seem to take in the contents of this file, i keep getting No such elements exception on line 25, all help appreciate. heres a link to the file link
heres my code
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class practiceFinal {
public static void main(String[] args) {
String fileName = args[0];
int length = fileLength(fileName);
int[] array = new int[length];
String[] list = new String[length];
arrayPopulate(array, list, fileName);
for (int i = 0; i < array.length; i++) {
System.out.print(array[i]);
}
}
public static int fileLength(String fileName) {
File file = new File(fileName);
Scanner fileScan = new Scanner(fileName);
int counter = 0;
while (fileScan.hasNext()) {
fileScan.next();
counter++;
}
return counter;
}
public static void arrayPopulate(int[] array, String[] list, String fileName) {
File file = new File(fileName);
Scanner fileScan = null;
try {
fileScan = new Scanner(file);
} catch (FileNotFoundException e) {
System.out.println("details: " + e.getMessage());
}
for (int i = 0; i < array.length; i++) {
array[i] = fileScan.nextInt();
list[i] = fileScan.next();
}
}
}
There are a few problems here. First of all you are using fileScan.next(); to try and get the length of a file. This is going to give you 2 times the length because you are counting each token fileScan.next() grabs which will be first the number and then the letter.
Length of lines is 144 but when you calculate it, it returns 288.
So use fileScan.nextLine();, now some people have mentioned this but your program is still not going to work correctly because you passed Scanner fileScan = new Scanner(fileName); // mistake passed fileName instead of file
Here are the changes I made inside the fileLength() method:
File file = new File(fileName);
Scanner fileScan = new Scanner(file); // mistake passed fileName instead of file, changed from Scanner fileScan = new Scanner(fileName)
while (fileScan.hasNextLine()) {
fileScan.nextLine(); // changed from fileScan.next()
counter++;
}
Your output looks like:
84c89C11w71h110B96d61H92d10B3p40c97G117X13....
When you are printing the results, change the print statements to
System.out.print(array[i]);
System.out.print(" " + list[i]);
System.out.println();
Output now looks like:
84 c
89 C
11 w
71 h
....
Instead of using int length = fileLength(fileName); to find the length, use int length = fileName.length();
From the format of your file and your current code, it looks like length represents the number of "words" in the file. In your loop, you need to advance i by 2 instead of 1, since it consumes two "words" per iteration. This also means that each array is twice as long as it should be. Instantiate them with length/2.
for (int i = 0; i < array.length; i += 2) {
array[i] = fileScan.nextInt();
list[i] = fileScan.next();
}
Alternately, you could make length represent the number of lines in the file. To do that, use hasNextLine() and nextLine() in your counting loop. Then leave all of the rest of your code as-is.
while (fileScan.hasNextLine()) {
fileScan.nextLine();
counter++;
}
Additionally, make sure your Scanner is passed the proper parameters. A String is valid, but not for File I/O. You would need to first create a File object using the fileName.
Scanner fileScan = new Scanner(new File(fileName));
I need to read file into the array long[], so the result will be same as creating new instance:
long [] y = new long[] {
500, 300, 16800, 35200,
60000, 50000, 2200, 2200, 29500
};
How can I do it?
try {
Scanner scanner = new Scanner(new File("myFile.txt"));
long[] values = new long[100];
int i = 0;
while (scanner.hasNextLong()) {
values[i] = scanner.nextLong();
i++;
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Try. Ugly, but should work
Scanner scanner = new Scanner(new File("myfile.txt"));
String[] numbersStrings = scanner.readLine().split(" ");
long[] numbers = new long[numbersStrings.length];
for (int i = 0; i < numbersStrings.length; i++) {
numbers[i] = Long.parseLong(numbersStrings[i]);
}
scanner.close();
You can use a Scanner, a List<Long> and a pair of loops (one to read the long(s) into a List then a second to convert the List to an array) with something like -
public static long[] readFile(String filePath) {
List<Long> al = new ArrayList<Long>();
File f = new File(filePath);
Scanner scanner = null;
try {
scanner = new Scanner(f);
while (scanner.hasNextLong()) {
al.add(scanner.nextLong());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (scanner != null) {
scanner.close();
}
}
long[] ret = new long[al.size()];
for (int i = 0; i < al.size(); i++) {
ret[i] = al.get(i);
}
return ret;
}
Using the previous answer as a base:
try (Scanner scanner : new Scanner(new File("myfile.txt")) {
List<Long> numbers = new ArrayList<>();
while (scanner.hasNextLong()) {
numbers.add(scanner.nextLong());
}
Long[] value = numbers.toArray(new Long[numbers.size()]);
// or:
long[] values = new long[numbers.size()];
int i = 0;
for (Long n : numbers) {
values[i] = n;
++i;
}
}
The try-with-resources is used to close the Scanner, and the file, when you're done reading it.
Scanner is a class that can read various thing, and among all, it can read Long.
We need to store the values inside an ArrayList because we don't know the amount of number there are in the file.
Converting the ArrayList is then a little tricky:
With auto boxing Long can be converted to long (and long to Long), but that don't work for arrays: Long[] is not a long[].
The first form use the toArray method, which return an array of Long.
The second form create an array of long[] and fill it with the numbers from the list using a for-each.
Scanner might be a bit slow for larger inputs. I recommend tokenizer
Also, this will be more memory effective since we're not allocating any extra Object (wrappers for primitives), and no extra temporary data structure (except tokenizer internals)
// Read the file into the string.
// WARNING: This will throw OutOfMemoryException on very large files
// To handle large file you will need to wrap the file into a buffer and read it partially.
// Also this method is present only in Java 7+ . If you're on 6, just use regular file reading
byte[] fileContent = Files.readAllBytes(Paths.get(path));
String str = new String(fileContent, encoding);
// The second parameter is the delimiter. If your data is separated by space, this will work.
// Otherwise (ex. by comma - ,) you will need to supply it here
StringTokenizer tokenizer = new StringTokenizer(str," ");
long[] values = new long[tokenizer.countTokens()];
int idx = 0;
while(tokenizer.hasMoreTokens()) {
values[idx++] = Long.parseLong(tokenizer.nextToken());
}
I'm trying to read a text file with this format:
Array x
1,3,5,4
Array y
12,13,15,11
and put it in two array, but I only want the integer.
What delimiter should I use to ignore the String and the empty line?
Here's my code in putting the int to arrays. By the way, I'm using scanner to read the file:
Scanner sc = null;
try
{
sc = new Scanner(new FileInputStream("C:\\x.txt"));
sc.useDelimiter(""); // What will I put inside a quote to get only the int values?
}
catch(Exception e)
{
System.out.println("file not found!");
}
int[] xArray = new int[4];
int[] yArray = new int[4];
while (sc.hasNextInt( )){
for(int i=0; i<4; i++){
xArray[i] = sc.nextInt( );
}
for(int i=0; i<4; i++){
yArray[i] = sc.nextInt( );
}
}
What I want to get is
int[] xArray = {1,3,5,4}
int[] yArray = {12,13,15,11}
I hope you understand :)
Thanks.
I suggest you to use bufferedreader instead of scanner. You can use below code :
BufferedReader br=new BufferedReader(new FileReader("your file name"));
br.readLine(); //it will omit first line Array x
String x=br.readLine(); //it return second line as a string
String[] x_value=x.split(","); //You can parse string array into int.
This is for Array x. You can do the same for array y. and after that parse into int.
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();
}
}