I'm trying to create a 2D array from a .txt file, where the .txt file looks something like this:
xxxx
xxxx
xxxx
xxxx
or something like this:
xxx
xxx
xxx
So I need to handle multiple sizes of a 2D array (Note: Each 2D array will not always be equal x and y dimensions). Is there anyway to initialize the array, or get the number of characters/letters/numbers per line and number of columns? I do not want to use a general statement, something like:
String[][] myArray = new Array[100][100];
And then would filling the array using filewriter and scanner classes look like this?
File f = new File(filename);
Scanner input = new Scanner(f);
for(int i = 0; i < myArray[0][].length; i++){
for(int j = 0; j < myArray[][0].length, j++){
myArray[i][j] = input.nextLine();
}
}
You have several choices as I see it:
Iterate through the file twice, the first time getting the array parameters, or
Iterate through it once, but fill up a List<List<SomeType>> possibly instantiating your Lists as ArrayLists. The latter will give you much greater flexibility in the short and long run.
(per MadProgrammer) The third option is to re-structure the file to provide the meta data required to make decisions about the size of the array.
For example, using your code,
File f = new File(filename);
Scanner input = new Scanner(f);
List<List<String>> nestedLists = new ArrayList<>();
while (input.hasNextLine()) {
String line = input.nextLine();
List<String> innerList = new ArrayList<>();
Scanner innerScanner = new Scanner(line);
while (innerScanner.hasNext()) {
innerList.add(innerScanner.next());
}
nestedLists.add(innerList);
innerScanner.close();
}
input.close();
Java Matrix can have each line (which is an array) by your size desicion.
You can use: ArrayUtils.add(char[] array, char element) //static method
But before that, you need to check what it the file lines length
Either this, you can also use ArrayList> as a collection which is holding your data
I am trying to read the x,y coordinates from a file that has 1000 entries.
This is what I have so far:
int n=4;
Point2D []p = new Point2D[n];
p[0] = new Point2D(4,5);
p[1] = new Point2D(5,3);
p[2] = new Point2D(1,4);
p[3] = new Point2D(6,1);
I can open the file like this:
Scanner numFile = new Scanner(new File("myValues.txt"));
ArrayList<Double> p = new ArrayList<Double>();
while (numFile.hasNextLine()) {
String line = numFile.nextLine();
Scanner sc = new Scanner(line);
sc.useDelimiter(" ");
while(sc.hasNextDouble()) {
p.add(sc.nextDouble());
}
sc.close();
}
numFile.close();
But I do not know how to create arrays with two values each time.
Please let me know if you need more information.
All you really need to do is create a Point2D object (using the coords in your .txt file) at each iteration of the loop, then add that object to your array list of Point2D objects:
For example:
ArrayList<Points2D> p = new ArrayList<>();
Scanner numFile = new Scanner(new File("myValues.txt"));
String pointOnLine = numFile.readLine();
while (numFile != null) //if line exists
{
String[] pointToAdd = pointOnLine.split(" +"); //get x y coords from each line, using a white space delimiter
//create point2D object, then add it to the list
Point2D pointFromFile = new Point2D(Integer.parseInt(pointToAdd[0]), Integer.parseInt(pointToAdd[1]));
p.add(pointFromFile);
numFile = numFile.readLine(); //assign numFile to the next line to be read
}
The tricky part (and the part you're stuck at I'm assuming), is extracting the individual x and y-coordinates from the file.
What I have done above was use the .split() method to turn every single line into a string array of each number on the entire line, separated by a white space. Since each line should only contain two numbers (x and y), the array size will be 2 (elements 0 and 1 respectively).
From there, we simply get the first element in the string array (the x-coordinate), and the second element (the y-coordinate), and then parse those strings into integers.
Now that we have isolated the x and y from each line, we use them to create the Point2D object, and then add that object to the array list.
Hope this clarifies things
I need to make a program which reads a file in a method. The file is a "data.txt" type and will have a list of numbers (double data type) with one number on each line.
Ex:
23.4
12.3
111.4533
I need to then put this in an array (NOT a 2D array)and return it to the main method.
I used filename.length() but it makes the array size larger than it should be and I'm getting an array out of bounds error.
I can initialize the array in a while loop, but it keeps saying I need to declare the size of the array first and I don't know how to do this. So I tried just using a while loop to get the number of lines and then using another loop to input the elements but it won't let me return the array to the main method without initializing the array. Here's what I have so far:
java.io.File file = new java.io.File(file);
int arraySize = (int)file.length();
int size = 0;
int i = 0;
try{
Scanner input = new Scanner(file);
while(input.hasNextLine()){
size++;
}
double [] array;
array1 = new double [size];
while(input.hasNext()){
array[i] = input.nextDouble();
i++;
}
Any suggestions? I'm really stuck on this. Thanks.
Two possible solutions:
a) Use a collection which grows on demand instead of using a fixed array (e.g., ArrayList). You can also convert it afterwards into an array again.
b) Close the scanner and open the file again after you counted the number of lines.
The problem right now is that you are not redefining the Scanner, so after you determine the size, the Scanner is at the end of the file and so there are no more doubles to be read in.
Also, when determining the size, you need to actually read in the line each loop so you skip to new lines, or else I think you will have an infinite loop. If you never read in a line, it always has more.
Try this (tested and works):
java.io.File file = new java.io.File(file);
int size = 0;
int i = 0;
try {
Scanner input = new Scanner(file);
while(input.hasNextLine()){
input.nextLine(); // have to change the lines
size++;
}
double [] array;
array = new double [size];
// reopen the file so you start from the beginning again
input = new Scanner(file);
while(input.hasNext()){
array[i] = input.nextDouble();
i++;
}
// print out the array
for (double d : array) {
System.out.println(d);
}
} catch (Exception e) {
e.printStackTrace();
}
Or you could just use an ArrayList which has no defined size (you can .add elements to it and so you don't need to know the size beforehand to populate it). And then just convert the ArrayList to a regular array afterword if you wanted to.
Try this:
java.io.File file = new java.io.File("C:\\Users\\Mike\\Desktop\\data.txt");
try {
Scanner input = new Scanner(file);
ArrayList<Double> list = new ArrayList<Double>(); // define empty ArrayList
while(input.hasNextLine()) {
list.add(input.nextDouble()); // have to change the lines
}
// convert ArrayList to array
// (although you don't need to do this if you're fine with an ArrayList)
double[] array = new double[list.size()];
for (int i = 0; i < list.size(); i++) {
array[i] = list.get(i);
}
// print out the array
for (double d : array) {
System.out.println(d);
}
} catch (Exception e) {
e.printStackTrace();
}
Assuming your filename variable is a String of the file's name then filename.length is only giving you the total characters in the name. If you have called your File object filename then filename.length() returns a long of the file's length in bytes and not the number of rows inside it.
To get the number of lines in a file you can refer to this question for many possible answers: Number of lines in a file in Java
But more likely you want to use an expandable Collection instead of a fixed length array as you do not then need to calculate and read the whole file before you begin using it. Something like an ArrayList could be ideal. But it does depend on your use case.
You can always convert the ArrayList back to an Array afterwards:
String[] lines = lineList.toArray(new String[lineList.size()]);
I would recommend using an ArrayList. That way you don't have to be aware of the size while creating the array. As other's have said, you can convert to a array after you are done adding values to the ArrayList.
Assuming your data.txt file has your doubles line by line with no spaces. you could use the following code:
ArrayList <Double> doubleArray = new ArrayList<Double>();
Scanner fileScan = null;
try {
fileScan = new Scanner(new File("/path/to/file"));
while (fileScan.hasNextDouble()){
doubleArray.add(fileScan.nextDouble());
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
use below code
read line by line of text file and parse each line element to double
add double parsed value to arraylist
convert arraylist to array.
String fileName=null;
File file = null;
try {
fileName="path/filename.txt";
file = new File(fileName);
} catch (Exception e) {
System.out.println(e.getMessage());
// TODO: handle exception
}
List<Double> elements = new ArrayList<>();
try{
Scanner input = new Scanner(file);
while(input.hasNextLine()){
elements.add(Double.parseDouble(input.nextLine()));
}
double[] ret = new double[elements.size()];
for(int index = 0;index < ret.length;index++)
ret[index] = elements.get(index);
System.out.println(ret);
System.out.println("end");
}
catch(Exception e){
}
How would you write this code?
This particular question is about a maze game that has an arraylist of occupants which are Explorers (you), Monsters (touching will kill you), and Treasures. The game uses blocks of square objects in which these occupants reside in. The particular thing I want to do is file reading which can export the current configuration of the maze or import them as a txt file.
The specs:
First read in the rows and cols of the Maze to create a Square[][] of the appropriate size. Then construct and read in all the Squares/Occupants.
For Squares, the Maze will first determine that the line starts with "Square". It will then read in the row and col of the Square and use that information to construct a Square object. Finally it will pass the rest of the Scanner to the Square's toObject method so it can initialize itself.
For all other Occupants, the Maze will determine what kind of Occupant it is and construct the appropriate object using the constructor that only takes a Maze. It will not read the row or the col from the Scanner, but simply pass the Scanner on to the toObject method of the newly created object.
This is code that I have so far which could be wrong:
public void readMazeFromFile(String fileName) throws IOException, FileNotFoundException, MazeReadException
{
Scanner fileSc = new Scanner(new File(fileName));
String line = fileSc.nextLine(); //whats on the line, will be overwritten
Scanner lineSc = new Scanner(line);
String temp;
lineSc.useDelimiter(",");
int lineNum = 1; //every time you scan a line out, do lineNum++
int r1, r2, r3, r4, c1, c2, c3, c4;
rows = fileSc.nextInt();
cols = fileSc.nextInt();
Square hi = new Square(rows, cols);
line = fileSc.nextLine();
while ( line != null)
{
line = lineSc.nextLine();
lineSc = new Scanner(line);
if( lineSc.equals("Square"))
{
r1 = lineSc.nextInt();
c1 = lineSc.nextInt();
hi.toObject(lineSc);
}
if (lineSc.equals("Explorer"))
{
explorer.toObject(lineSc);
}
if (lineSc.equals("Treasure"))
{
Treasure.toObject(lineSc);
}
lineNum++;
}
Here is sample output:
5,5
Square,0,0,true,false,false,true,true,true
Square,0,1,true,false,true,false,true,true
Square,0,2,true,false,true,false,false,false
Square,0,3,true,false,false,false,false,false
Square,0,4,true,true,false,false,false,false
Square,1,0,false,false,true,true,true,true
Square,1,1,true,false,true,false,false,false
Square,1,2,true,true,false,false,false,false
Square,1,3,false,true,false,true,false,false
Square,1,4,false,true,false,true,false,false
Square,2,0,true,false,false,true,false,false
Square,2,1,true,false,true,false,false,false
Square,2,2,false,true,false,false,false,false
Square,2,3,false,true,false,true,false,false
Square,2,4,false,true,false,true,false,false
Square,3,0,false,true,false,true,false,false
Square,3,1,true,false,false,true,false,false
Square,3,2,false,true,false,false,false,false
Square,3,3,false,true,true,true,false,false
Square,3,4,false,true,false,true,false,false
Square,4,0,false,true,true,true,false,false
Square,4,1,false,true,true,true,false,false
Square,4,2,false,false,true,true,false,false
Square,4,3,true,false,true,false,false,false
Square,4,4,false,true,true,false,false,false
Explorer,0,0,Scary Name
Treasure,4,4,true
Treasure,2,2,false
Monster,4,4
Monster,3,3
What would you write for this section?
This is a skeleton that you can start with. You really don't need anything more than a Scanner here; it can do everything that you'd need to scan the input and do the conversion, etc. You want to use its next(), nextInt(), nextBoolean() and nextLine() methods.
Scanner in = new Scanner(new File(filename));
in.useDelimiter("\\s+|,");
int rows = in.nextInt();
int cols = in.nextInt();
// construct the array
while (in.hasNext()) {
String type = in.next();
int r = in.nextInt();
int c = in.nextInt();
// read more depending on type
}
Use a
FileReader
on the file and then attach a
StreamTokenizer
to that, far more efficient :)